[
  {
    "path": ".github/workflows/ci.yaml",
    "content": "\nname: CI Actions\npermissions:\n  contents: read\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\njobs:\n  workflow:\n    name: Lint/Build/Test\n\n    strategy:\n      matrix:\n        go-version: [1.21.x]\n        os: [ ubuntu-latest ]\n    runs-on: ${{ matrix.os }}\n\n    steps:\n      - name: Install Go\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{matrix.go-version}}\n\n      - name: Checkout Code Base\n        uses: actions/checkout@v3\n        with:\n          fetch-depth: '0'\n\n      - name: Restore Go Module Cache\n        uses: actions/cache@v4\n        with:\n          path: ~/go/internal/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n\n      - name: Make Lint\n        run: |\n          export GOPATH=$HOME/go\n          export PATH=$PATH:$GOPATH/bin\n          curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.3\n          go mod tidy\n          make lint\n\n      - name: Test\n        run: make test\n\n      - name: Install goveralls\n        run: go install github.com/mattn/goveralls@latest\n\n      - name: Send coverage\n        env:\n          COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: goveralls -coverprofile=coverage.out -service=github\n"
  },
  {
    "path": ".gitignore",
    "content": "\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n\n.vscode\n.idea\n.DS_Store\n\n# Binary\nmain\nclickhouse-sql-parser"
  },
  {
    "path": ".golangci.yml",
    "content": "\n# This file contains all available configuration options\n# with their default values.\n\n# options for analysis running\nrun:\n  # default concurrency is a available CPU number\n  concurrency: 4\n\n  # timeout for analysis, e.g. 30s, 5m, default is 1m\n  timeout: 5m\n\n  # exit code when at least one issue was found, default is 1\n  issues-exit-code: 1\n\n  # include test files or not, default is true\n  tests: true\n\n  # list of build tags, all linters use it. Default is empty list.\n  build-tags:\n\n  # which dirs to skip: issues from them won't be reported;\n  # can use regexp here: generated.*, regexp is applied on full path;\n  # default value is empty list, but default dirs are skipped independently\n  # from this option's value (see skip-dirs-use-default).\n  skip-dirs:\n\n  # default is true. Enables skipping of directories:\n  #   vendor$, third_party$, testdata$, examples$, Godeps$, builtin$\n  skip-dirs-use-default: true\n\n  # which files to skip: they will be analyzed, but issues from them\n  # won't be reported. Default value is empty list, but there is\n  # no need to include all autogenerated files, we confidently recognize\n  # autogenerated files. If it's not please let us know.\n  skip-files:\n\n# output configuration options\noutput:\n  # colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions\n  # default is \"colored-line-number\"\n  format: colored-line-number\n\n  # print lines of code with issue, default is true\n  print-issued-lines: true\n\n  # print linter name in the end of issue text, default is true\n  print-linter-name: true\n\n  # make issues output unique by line, default is true\n  uniq-by-line: true\n\n  # add a prefix to the output file references; default is no prefix\n  path-prefix: \"\"\n\n  # sorts results by: filepath, line and column\n  sort-results: false\n\n\n# all available settings of specific linters\nlinters-settings:\n  dogsled:\n    # checks assignments with too many blank identifiers; default is 2\n    max-blank-identifiers: 2\n\n  dupl:\n    # tokens count to trigger issue, 150 by default\n    threshold: 100\n\n  errcheck:\n    # default is false: such cases aren't reported by default.\n    check-type-assertions: false\n\n    # default is false: such cases aren't reported by default.\n    check-blank: false\n\n    # list of functions to exclude from checking, where each entry is a single function to exclude.\n    # see https://github.com/kisielk/errcheck#excluding-functions for details\n    exclude-functions:\n\n  errchkjson:\n    # with check-error-free-encoding set to true, errchkjson does warn about errors\n    # from json encoding functions that are safe to be ignored,\n    # because they are not possible to happen (default false)\n    #\n    # if check-error-free-encoding is set to true and errcheck linter is enabled,\n    # it is recommended to add the following exceptions to prevent from false positives:\n    #\n    #     linters-settings:\n    #       errcheck:\n    #         exclude-functions:\n    #           - encoding/json.Marshal\n    #           - encoding/json.MarshalIndent\n    #           - (*encoding/json.Encoder).Encode\n    check-error-free-encoding: false\n    # if report-no-exported is true, encoding a struct without exported fields is reported as issue (default false)\n    report-no-exported: false\n\n  errorlint:\n    # Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats\n    errorf: true\n    # Check for plain type assertions and type switches\n    asserts: true\n    # Check for plain error comparisons\n    comparison: true\n\n  funlen:\n    lines: 100\n    statements: 60\n\n  gocognit:\n    # minimal code complexity to report, 30 by default (but we recommend 10-20)\n    min-complexity: 20\n\n  goconst:\n    # minimal length of string constant, 3 by default\n    min-len: 3\n    # minimum occurrences of constant string count to trigger issue, 3 by default\n    min-occurrences: 3\n    # ignore test files, false by default\n    ignore-tests: false\n    # look for existing constants matching the values, true by default\n    match-constant: true\n    # search also for duplicated numbers, false by default\n    numbers: false\n    # minimum value, only works with goconst.numbers, 3 by default\n    min: 3\n    # maximum value, only works with goconst.numbers, 3 by default\n    max: 3\n    # ignore when constant is not used as function argument, true by default\n    ignore-calls: true\n\n  gocritic:\n    # Which checks should be enabled; can't be combined with 'disabled-checks';\n    # See https://go-critic.github.io/overview#checks-overview\n    # By default list of stable checks is used.\n    enabled-checks:\n\n    # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section \"Tags\".\n    enabled-tags:\n      - performance\n\n    # Settings passed to gocritic.\n    # The settings key is the name of a supported gocritic checker.\n    # The list of supported checkers can be find in https://go-critic.github.io/overview.\n    settings:\n      captLocal: # must be valid enabled check name\n        # whether to restrict checker to params only (default true)\n        paramsOnly: true\n      elseif:\n        # whether to skip balanced if-else pairs (default true)\n        skipBalanced: true\n      hugeParam:\n        # size in bytes that makes the warning trigger (default 80)\n        sizeThreshold: 80\n      rangeExprCopy:\n        # size in bytes that makes the warning trigger (default 512)\n        sizeThreshold: 512\n        # whether to check test functions (default true)\n        skipTestFuncs: true\n      rangeValCopy:\n        # size in bytes that makes the warning trigger (default 128)\n        sizeThreshold: 128\n        # whether to check test functions (default true)\n        skipTestFuncs: true\n      underef:\n        # whether to skip (*x).method() calls where x is a pointer receiver (default true)\n        skipRecvDeref: true\n\n  gocyclo:\n    # minimal code complexity to report, 30 by default (but we recommend 10-20)\n    min-complexity: 10\n\n  godot:\n    scope: declarations\n    # list of regexps for excluding particular comment lines from check\n    exclude:\n    # example: exclude comments which contain numbers\n    # - '[0-9]+'\n    # check that each sentence starts with a capital letter\n    capital: false\n\n  godox:\n    # report any comments starting with keywords, this is useful for TODO or FIXME comments that\n    # might be left in the code accidentally and should be resolved before merging\n    keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting\n\n  gofmt:\n    simplify: true\n\n  goimports:\n    # put imports beginning with prefix after 3rd-party packages;\n    # it's a comma-separated list of prefixes\n    local-prefixes:\n\n  golint:\n    # minimal confidence for issues, default is 0.8\n    min-confidence: 0.8\n\n  gomnd:\n    settings:\n      mnd:\n        # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.\n        checks: argument,case,condition,operation,return,assign\n        # ignored-numbers: 1000\n        # ignored-files: magic_.*.go\n        # ignored-functions: math.*\n\n  gomoddirectives:\n    replace-local: false\n    replace-allow-list:\n    retract-allow-no-explanation: false\n    exclude-forbidden: false\n\n  gomodguard:\n    allowed:\n      modules:                                                        # List of allowed modules\n      # - gopkg.in/yaml.v2\n      domains:                                                        # List of allowed module domains\n      # - golang.org\n    blocked:\n      modules:                                                        # List of blocked modules\n      # - github.com/uudashr/go-module:                               # Blocked module\n      #     recommendations:                                          # Recommended modules that should be used instead (Optional)\n      #       - golang.org/x/mod\n      versions:                                                       # List of blocked module version constraints\n      # - github.com/mitchellh/go-homedir:                            # Blocked module with version constraint\n      #     version: \"< 1.1.0\"                                        # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons\n      #     reason: \"testing if blocked version constraint works.\"    # Reason why the version constraint exists. (Optional)\n      local_replace_directives: false                                 # Set to true to raise lint issues for packages that are loaded from a local path via replace directive\n\n  gosec:\n    # To select a subset of rules to run.\n    # Available rules: https://github.com/securego/gosec#available-rules\n    includes:\n      - G401\n      - G306\n      - G101\n    # To specify a set of rules to explicitly exclude.\n    # Available rules: https://github.com/securego/gosec#available-rules\n    excludes:\n      - G204\n    # Exclude generated files\n    exclude-generated: true\n    # Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high.\n    severity: \"low\"\n    # Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high.\n    confidence: \"low\"\n    # To specify the configuration of rules.\n    # The configuration of rules is not fully documented by gosec:\n    # https://github.com/securego/gosec#configuration\n    # https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102\n    config:\n      G306: \"0600\"\n      G101:\n        pattern: \"(?i)example\"\n        ignore_entropy: false\n        entropy_threshold: \"80.0\"\n        per_char_threshold: \"3.0\"\n        truncate: \"32\"\n\n  gosimple:\n    # Select the Go version to target. The default is '1.13'.\n    go: \"1.15\"\n    # https://staticcheck.io/docs/options#checks\n    checks: [ \"all\" ]\n\n  govet:\n    # report about shadowed variables\n    check-shadowing: false\n\n    # settings per analyzer\n    settings:\n      printf:\n        funcs:\n          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof\n          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf\n          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf\n          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf\n\n    # enable or disable analyzers by name\n    enable:\n      # - atomicalign\n    enable-all: true\n    disable:\n      - shadow\n      - fieldalignment\n    disable-all: false\n\n  depguard:\n    list-type: blacklist\n    include-go-root: false\n    packages:\n      # - github.com/sirupsen/logrus\n    packages-with-error-message:\n      # specify an error message to output when a blacklisted package is used\n      # - github.com/sirupsen/logrus: \"logging is allowed only by logutils.Log\"\n\n  ifshort:\n    # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax.\n    # Has higher priority than max-decl-chars.\n    max-decl-lines: 1\n    # Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax.\n    max-decl-chars: 30\n\n  lll:\n    # max line length, lines longer will be reported. Default is 120.\n    # '\\t' is counted as 1 character by default, and can be changed with the tab-width option\n    line-length: 160\n    # tab width in spaces. Default to 1.\n    tab-width: 4\n\n  makezero:\n    # Allow only slices initialized with a length of zero. Default is false.\n    always: false\n\n  maligned:\n    # print struct with more effective memory layout or not, false by default\n    suggest-new: true\n\n  misspell:\n    # Correct spellings using locale preferences for US or UK.\n    # Default is to use a neutral variety of English.\n    # Setting locale to US will correct the British spelling of 'colour' to 'color'.\n    locale: US\n    ignore-words:\n      - automizely\n\n  nakedret:\n    # make an issue if func has more lines of code than this setting and it has naked returns; default is 30\n    max-func-lines: 30\n\n  nestif:\n    # minimal complexity of if statements to report, 5 by default\n    min-complexity: 5\n\n  nlreturn:\n    # size of the block (including return statement that is still \"OK\")\n    # so no return split required.\n    block-size: 1\n\n  nolintlint:\n    # Disable to ensure that all nolint directives actually have an effect. Default is false.\n    allow-unused: false\n    # Disable to ensure that nolint directives don't have a leading space. Default is true.\n    allow-leading-space: true\n    # Exclude following linters from requiring an explanation.  Default is [].\n    allow-no-explanation: [ ]\n    # Enable to require an explanation of nonzero length after each nolint directive. Default is false.\n    require-explanation: false\n    # Enable to require nolint directives to mention the specific linter being suppressed. Default is false.\n    require-specific: false\n\n  prealloc:\n    # XXX: we don't recommend using this linter before doing performance profiling.\n    # For most programs usage of prealloc will be a premature optimization.\n\n    # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.\n    # True by default.\n    simple: true\n    range-loops: true # Report preallocation suggestions on range loops, true by default\n    for-loops: false # Report preallocation suggestions on for loops, false by default\n\n  promlinter:\n    # Promlinter cannot infer all metrics name in static analysis.\n    # Enable strict mode will also include the errors caused by failing to parse the args.\n    strict: false\n    # Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.\n    disabled-linters:\n    #  - \"Help\"\n    #  - \"MetricUnits\"\n    #  - \"Counter\"\n    #  - \"HistogramSummaryReserved\"\n    #  - \"MetricTypeInName\"\n    #  - \"ReservedChars\"\n    #  - \"CamelCase\"\n    #  - \"lintUnitAbbreviations\"\n\n  predeclared:\n    # comma-separated list of predeclared identifiers to not report on\n    ignore: \"\"\n    # include method names and field names (i.e., qualified names) in checks\n    q: false\n\n  rowserrcheck:\n    packages:\n      - github.com/jmoiron/sqlx\n\n  revive:\n    # see https://github.com/mgechev/revive#available-rules for details.\n    ignore-generated-header: true\n    severity: warning\n    rules:\n      - name: indent-error-flow\n        severity: warning\n\n  staticcheck:\n    # Select the Go version to target. The default is '1.13'.\n    go: \"1.15\"\n    # https://staticcheck.io/docs/options#checks\n    checks: [ \"all\" ]\n\n  stylecheck:\n    # Select the Go version to target. The default is '1.13'.\n    go: \"1.15\"\n    # https://staticcheck.io/docs/options#checks\n    checks: [ \"all\", \"-ST1000\", \"-ST1003\", \"-ST1016\", \"-ST1020\", \"-ST1021\", \"-ST1022\" ]\n    # https://staticcheck.io/docs/options#dot_import_whitelist\n    dot-import-whitelist:\n    # https://staticcheck.io/docs/options#initialisms\n    initialisms: [ \"ACL\", \"API\", \"ASCII\", \"CPU\", \"CSS\", \"DNS\", \"EOF\", \"GUID\", \"HTML\", \"HTTP\", \"HTTPS\", \"ID\", \"IP\", \"JSON\", \"QPS\", \"RAM\", \"RPC\", \"SLA\", \"SMTP\", \"SQL\", \"SSH\", \"TCP\", \"TLS\", \"TTL\", \"UDP\", \"UI\", \"GID\", \"UID\", \"UUID\", \"URI\", \"URL\", \"UTF8\", \"VM\", \"XML\", \"XMPP\", \"XSRF\", \"XSS\" ]\n    # https://staticcheck.io/docs/options#http_status_code_whitelist\n    http-status-code-whitelist: []\n\n  tagliatelle:\n    # check the struck tag name case\n    case:\n      # use the struct field name to check the name of the struct tag\n      use-field-name: true\n      rules:\n        # any struct tag type can be used.\n        json: snake\n\n  testpackage:\n    # regexp pattern to skip files\n    skip-regexp: (export|internal)_test\\.go\n\n  unparam:\n    # Inspect exported functions, default is false. Set to true if no external program/library imports your code.\n    # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:\n    # if it's called for subdir of a project it can't find external interfaces. All text editor integrations\n    # with golangci-lint call it on a directory with the changed file.\n    check-exported: false\n\n  unused:\n    # Select the Go version to target. The default is '1.13'.\n    go: \"1.15\"\n\n  whitespace:\n    multi-if: false   # Enforces newlines (or comments) after every multi-line if statement\n    multi-func: false # Enforces newlines (or comments) after every multi-line function signature\n\n  wsl:\n    allow-assign-and-anything: false\n    allow-assign-and-call: true\n    allow-cuddle-declarations: false\n    allow-multiline-assign: true\n    allow-separated-leading-comment: false\n    allow-trailing-comment: false\n    force-case-trailing-whitespace: 0\n    force-err-cuddling: false\n    force-short-decl-cuddling: false\n    strict-append: true\n\nlinters:\n  enable:\n    - dogsled\n    - forcetypeassert\n    - funlen\n    - goconst\n    - govet\n    - gofmt\n    - goimports\n    - lll\n    - megacheck\n    - misspell\n    - revive\n  disable:\n    - maligned\n    - prealloc\n    - scopelint\n    - nilnil\n  disable-all: false\n  presets:\n    - bugs\n    - unused\n    - sql\n  fast: false\n\nissues:\n  # List of regexps of issue texts to exclude, empty list by default.\n  # But independently from this option we use default exclude patterns,\n  exclude:\n    - G404\n    - SA1029\n\n  # Excluding configuration per-path, per-linter, per-text and per-source\n  exclude-rules:\n    # Exclude some linters from running on tests files.\n    - path: _test\\.go\n      linters:\n        - cyclop\n        - dupl\n        - errcheck\n        - funlen\n        - gocognit\n        - goconst\n        - gocritic\n        - gocyclo\n        - gosec\n        - lll\n        - thelper\n        - wrapcheck\n\n    # Exclude known linters from partially hard-vendored code,\n    # which is impossible to exclude via \"nolint\" comments.\n    - path: internal/hmac/\n      text: \"weak cryptographic primitive\"\n      linters:\n        - gosec\n\n    # Exclude some staticcheck messages\n    - linters:\n        - staticcheck\n      text: \"SA9003:\"\n\n    # Exclude lll issues for long lines with go:generate\n    - linters:\n        - lll\n      source: \"^//go:generate \"\n\n  # Default value for this option is true.\n  exclude-use-default: true\n\n  # The default value is false. If set to true exclude and exclude-rules\n  # regular expressions become case sensitive.\n  exclude-case-sensitive: false\n\n  # The list of ids of default excludes to include or disable. By default it's empty.\n  include:\n    # - EXC0002 # disable excluding of issues about comments from golint\n\n  # Maximum issues count per one linter. Set to 0 to disable. Default is 50.\n  max-issues-per-linter: 0\n\n  # Maximum count of issues with the same text. Set to 0 to disable. Default is 3.\n  max-same-issues: 0\n\n  # Show only new issues: if there are unstaged changes or untracked files,\n  # only those changes are analyzed, else only changes in HEAD~ are analyzed.\n  # It's a super-useful option for integration of golangci-lint into existing\n  # large codebase. It's not practical to fix all existing issues at the moment\n  # of integration: much better don't allow issues in new code.\n  # Default is false.\n  new: true\n\n  new-from-rev: \"\"\n\n  # Show only new issues created in git patch with set file path.\n  new-from-patch:\n\n  # Fix found issues (if it's supported by the linter)\n  fix: true\n\nseverity:\n  # Default value is empty string.\n  # Set the default severity for issues. If severity rules are defined and the issues\n  # do not match or no severity is provided to the rule this will be the default\n  # severity applied. Severities should match the supported severity names of the\n  # selected out format.\n  # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity\n  # -   Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity\n  # -       GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message\n  default-severity: error\n\n  # The default value is false.\n  # If set to true severity-rules regular expressions become case sensitive.\n  case-sensitive: false\n\n  # Default value is empty list.\n  # When a list of severity rules are provided, severity information will be added to lint\n  # issues. Severity rules have the same filtering capability as exclude rules except you\n  # are allowed to specify one matcher per severity rule.\n  # Only affects out formats that support setting severity information.\n  rules:\n    - linters:\n        - dupl\n      severity: info\n"
  },
  {
    "path": "AGENTS.md",
    "content": "# AI Agents Guidline\n\nThis document outlines guidance for AI coding agent including project structure, coding style, testing, and contribution practices for the ClickHouse SQL Parser project.\n\n\n## Development Commands\n\n```shell\n# Build the CLI binary\nmake\n\n# Run tests\nmake test\n\n# Update golden fixtures after intentional output changes\nmake update_test\n```\n\nAfter editing code, use `goimports` and `gofmt` to maintain code style, and run `make lint` to check for any issues before committing or requesting a review.\n\n## Project Structure & Module Organization\n- `main.go` is the CLI entry point (`clickhouse-sql-parser`) for AST output and SQL formatting.\n- `parser/` contains core parser code: lexer (`lexer.go`), AST definitions (`ast.go`), traversal helpers (`walk.go`), and grammar-specific parser files (`parser_query.go`, `parser_table.go`, `parser_alter.go`, etc.).\n- Tests live next to source as `*_test.go` files, with fixtures under `parser/testdata/`.\n- Fixture groups are organized by SQL type (`basic/`, `query/`, `dml/`, `ddl/`), with generated expectations in `output/` (AST JSON) and `format/` (formatted SQL).\n\n## Coding Style & Naming Conventions\n- Use Go 1.21 conventions (`go.mod`) and keep code `gofmt`/`goimports` clean (enforced by lint).\n- Naming is the most important style aspect, try you best to choose a clear and descriptive name for variables, functions, types, and files. For example, use `parseSelect` for a function that parses a SELECT statement, and `SelectStatement` for the corresponding AST node type.\n- Place parsing logic in the matching module by statement family (for example, query parsing in `parser/parser_query.go`).\n- Follow existing parser naming patterns such as `parseXxx` helpers and explicit AST type names.\n- Keep AST `FormatSQL()` output deterministic; formatting changes must be reflected in golden files.\n- You must go through the repository before adding new code to ensure consistency with existing patterns and styles. If you are unsure about where to place new code or how to format it, please refer to the existing codebase or ask for guidance.\n- Reusing existing code and patterns is encouraged to maintain consistency and reduce redundancy. If you find a similar function or pattern in the codebase, consider adapting it for your needs instead of creating something new from scratch.\n\n## Testing Guidelines\n- Use Go’s `testing` package with `testify/require` assertions and `goldie` snapshot comparisons.\n- Add new SQL cases as `.sql` files under the appropriate `parser/testdata/<category>/` directory.\n- If expected outputs change, run `make update_test` and commit updated files in both `output/` and/or `format/`.\n- Prefer descriptive test names (`TestParser_*`, `TestWalk_*`) and subtests for per-fixture coverage.\n\n## Commit & Pull Request Guidelines\n- Match existing commit style: concise, imperative subjects like `Add support for ...` or `Fix parsing failure ...`, optionally with issue refs (for example `(#235)`).\n- Keep PRs focused; describe grammar/AST impact, include representative SQL examples, and note regenerated fixtures.\n- Before requesting review, run `make lint` and `make test` locally to mirror CI expectations.\n\n\n## Important Notes\n\n- You must confirm it's correctly added to `visitor.go`, `walk.go` and `format.go` when adding a new expression or statement type. This ensures that the new AST node is properly traversed and formatted.\n- Newly added test cases must be concise and cover the core functionality being tested first.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 AfterShip\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "\nPROGRAM=clickhouse-sql-parser\nPKG_FILES=`go list ./... | sed -e 's=github.com/AfterShip/clickhouse-sql-parser/=./='`\n\nCCCOLOR=\"\\033[37;1m\"\nMAKECOLOR=\"\\033[32;1m\"\nENDCOLOR=\"\\033[0m\"\n\nall: $(PROGRAM)\n\n.PHONY: all\n\n$(PROGRAM):\n\tgo build -o $(PROGRAM) main.go\n\ntest:\n\t@go test -v ./... -covermode=atomic -coverprofile=coverage.out -race -compatible\n\nupdate_test:\n\t@go test -v ./... -update -race -compatible\n\nlint:\n\t@printf $(CCCOLOR)\"GolangCI Lint...\\n\"$(ENDCOLOR)\n\t@golangci-lint run --timeout 20m0s\n"
  },
  {
    "path": "README.md",
    "content": "# ClickHouse SQL Parser \n![GitHub CI](https://github.com/AfterShip/clickhouse-sql-parser/actions/workflows/ci.yaml/badge.svg) [![Go Report Card](https://goreportcard.com/badge/github.com/AfterShip/clickhouse-sql-parser)](https://goreportcard.com/report/github.com/AfterShip/clickhouse-sql-parser) [![LICENSE](https://img.shields.io/github/license/AfterShip/clickhouse-sql-parser.svg)](https://github.com/AfterShip/clickhouse-sql-parser/blob/master/LICENSE) [![GoDoc](https://img.shields.io/badge/Godoc-reference-blue.svg)](https://godoc.org/github.com/AfterShip/clickhouse-sql-parser) [![Coverage Status](https://coveralls.io/repos/github/AfterShip/clickhouse-sql-parser/badge.svg?branch=master)](https://coveralls.io/github/AfterShip/clickhouse-sql-parser?branch=master) <a href=\"https://hellogithub.com/repository/23597949cafa410bba6039ddb8867543\" target=\"_blank\"><img src=\"https://api.hellogithub.com/v1/widgets/recommend.svg?rid=23597949cafa410bba6039ddb8867543&claim_uid=kyCYu1VAKgwD8rE&theme=small\" alt=\"Featured｜HelloGitHub\" /></a>\n\nThe goal of this project is to build a ClickHouse SQL parser in Go with the following key features:\n\n- Parse ClickHouse SQL into AST\n- Beautify ClickHouse SQL format\n\nThis project is inspired by [memefish](https://github.com/cloudspannerecosystem/memefish) which is a SQL parser for Spanner in Go.\n## How to use\n\nYou can use it as your Go library or CLI tool, see the following examples:\n\n- Use clickhouse-sql-parser as a Go library\n\n```Go\npackage main\n\nimport (\n    clickhouse \"github.com/AfterShip/clickhouse-sql-parser/parser\"\n)\n\nquery := \"SELECT * FROM clickhouse\"\nparser := clickhouse.NewParser(query)\n// Parse query into AST\nstatements, err := parser.ParseStmts()\nif err != nil {\n    return nil, err\n}\n```\n\n- Install clickhouse-sql-parser as a CLI tool\n\n\nOn Linux:\n\n```bash\n$ go install github.com/AfterShip/clickhouse-sql-parser@latest\n```\n\nOn macOS:\n\n```bash\n$ brew install clickhouse-sql-parser\n```\n\nParse ClickHouse SQL into AST or format ClickHouse SQL:\n\n```bash\n## Parse query into AST\n$ clickhouse-sql-parser \"SELECT * FROM clickhouse WHERE a=100\"\n\n## Format query (compact, single-line output)\n$ clickhouse-sql-parser -format \"SELECT * FROM clickhouse WHERE a=100\"\n\n## Beautify query (formatted with proper indentation and line breaks)\n$ clickhouse-sql-parser -beautify \"SELECT * FROM clickhouse WHERE a=100\"\n\n## Parse query from file\n$ clickhouse-sql-parser -f ./test.sql\n```\n\n### Beautify SQL Example\n\nThe `-beautify` flag formats SQL with proper indentation and line breaks, making complex queries more readable:\n\n```SQL\n# Input (compact, hard to read)\n$ clickhouse-sql-parser -beautify \"SELECT user_id, COUNT(*) AS total, AVG(amount) AS avg_amount FROM orders WHERE status='completed' AND created_at>'2024-01-01' GROUP BY user_id HAVING COUNT(*)>5 ORDER BY total DESC LIMIT 10\"\n\n# Output (beautified, easy to read)\nSELECT\n  user_id,\n  COUNT(*) AS total,\n  AVG(amount) AS avg_amount\nFROM orders\nWHERE\n  status = 'completed'\nAND\n  created_at > '2024-01-01'\nGROUP BY\n  user_id\nHAVING COUNT(*) > 5\nORDER BY\n  total DESC\nLIMIT 10\n```\n\n- Parsed tree(AST) back into a SQL statement\n\n```Go\nparser := clickhouse.NewParser(\"SELECT * FROM clickhouse\")\n// Parse query into AST\nstatements, err := parser.ParseStmts()\nif err != nil {\n    return nil, err\n}\n\n// Format AST back into a SQL string\nfor _, stmt := range statements {\n  fmt.Println(clickhouse.Format(stmt))\n}\n```\n\n## AST Traversal\n\n### Walk Pattern (Recommended)\n\nThe Walk pattern provides a simple and efficient way to traverse AST nodes. Use the `Walk` function to visit all nodes in the AST:\n\n```Go\nimport (\n    clickhouse \"github.com/AfterShip/clickhouse-sql-parser/parser\"\n)\n\nparser := clickhouse.NewParser(\"SELECT * FROM table WHERE id = 1\")\nstatements, err := parser.ParseStmts()\nif err != nil {\n    return err\n}\n\n// Walk through all nodes in the AST\nclickhouse.Walk(statements[0], func(node clickhouse.Expr) bool {\n    fmt.Printf(\"Node type: %T\\n\", node)\n    return true // return false to stop traversal for this subtree\n})\n```\n\n#### Walk Pattern Functions\n\n- **`Walk(node Expr, fn WalkFunc)`** - Traverses all nodes in depth-first order\n- **`WalkWithBreak(node Expr, fn WalkFunc)`** - Allows early termination of traversal\n- **`Find(root Expr, predicate func(Expr) bool)`** - Finds the first node matching a condition\n- **`FindAll(root Expr, predicate func(Expr) bool)`** - Finds all nodes matching a condition\n- **`Transform(root Expr, transformer func(Expr) Expr)`** - Applies transformations to nodes\n\n#### Examples\n\nFind all table identifiers:\n```Go\ntables := clickhouse.FindAll(stmt, func(node clickhouse.Expr) bool {\n    _, ok := node.(*clickhouse.TableIdentifier)\n    return ok\n})\n```\n\nFind the first WHERE clause:\n```Go\nwhereClause, found := clickhouse.Find(stmt, func(node clickhouse.Expr) bool {\n    _, ok := node.(*clickhouse.WhereClause)\n    return ok\n})\n```\n\n## Update test assets\n\nFor the files inside `output` and `format` dir are generated by the test cases,\n\nif you want to update them, you can run the following command:\n\n```bash\n$ make update_test\n```\n\n## Benchmarks\n\n```sh\ngo test -bench=. -benchmem ./parser\n```\n\nResults\n\n```\n$ go test -bench=. -benchmem ./parser\ngoos: linux\ngoarch: amd64\npkg: github.com/AfterShip/clickhouse-sql-parser/parser\ncpu: Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz\nBenchmarkParseSQLFiles/access_tuple_with_dot.sql-28                23294             58467 ns/op           13448 B/op        293 allocs/op\nBenchmarkParseSQLFiles/query_with_expr_compare.sql-28              43560             25704 ns/op            6240 B/op        132 allocs/op\nBenchmarkParseSQLFiles/select_cast.sql-28                          75055             16518 ns/op            4648 B/op         92 allocs/op\nBenchmarkParseSQLFiles/select_column_alias_string.sql-28          499798              2785 ns/op             704 B/op         13 allocs/op\nBenchmarkParseSQLFiles/select_expr.sql-28                         488187              2448 ns/op             696 B/op         12 allocs/op\nBenchmarkParseSQLFiles/select_item_with_modifiers.sql-28           54124             23305 ns/op            6232 B/op        136 allocs/op\nBenchmarkParseSQLFiles/select_order_by_timestamp.sql-28           232302              5809 ns/op            1368 B/op         28 allocs/op\nBenchmarkParseSQLFiles/select_simple.sql-28                        30602             50022 ns/op            9920 B/op        216 allocs/op\nBenchmarkParseSQLFiles/select_simple_field_alias.sql-28           178126              6316 ns/op            1712 B/op         39 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_bracket.sql-28           71902             16172 ns/op            3824 B/op         85 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_cte_with_column_aliases.sql-28                   67050             19916 ns/op            4648 B/op        101 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_group_by_with_cube_totals.sql-28                107047             10348 ns/op            2768 B/op         58 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_is_not_null.sql-28                               55285             21957 ns/op            5224 B/op        111 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_is_null.sql-28                                   66648             22412 ns/op            4728 B/op        102 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_top_clause.sql-28                               269910              4166 ns/op            1088 B/op         22 allocs/op\nBenchmarkParseSQLFiles/select_simple_with_with_clause.sql-28                               58494             18417 ns/op            5144 B/op        109 allocs/op\nBenchmarkParseSQLFiles/select_table_alias_without_keyword.sql-28                          121261             10011 ns/op            2896 B/op         65 allocs/op\nBenchmarkParseSQLFiles/select_table_function_with_query.sql-28                             98017             14929 ns/op            4168 B/op         81 allocs/op\nBenchmarkParseSQLFiles/select_when_condition.sql-28                                       220394              5457 ns/op            1304 B/op         28 allocs/op\nBenchmarkParseSQLFiles/select_with_distinct.sql-28                                        172948              6531 ns/op            1560 B/op         33 allocs/op\nBenchmarkParseSQLFiles/select_with_join_only.sql-28                                       286346              5594 ns/op            1520 B/op         32 allocs/op\nBenchmarkParseSQLFiles/select_with_left_join.sql-28                                        88200             13627 ns/op            3880 B/op         75 allocs/op\nBenchmarkParseSQLFiles/select_with_literal_table_name.sql-28                              241094              5099 ns/op            1304 B/op         27 allocs/op\nBenchmarkParseSQLFiles/select_with_multi_join.sql-28                                       44700             31964 ns/op            8240 B/op        188 allocs/op\nBenchmarkParseSQLFiles/select_with_multi_line_comment.sql-28                              363499              4460 ns/op             824 B/op         18 allocs/op\nBenchmarkParseSQLFiles/select_with_multi_union.sql-28                                     146233              7827 ns/op            2176 B/op         36 allocs/op\nBenchmarkParseSQLFiles/select_with_number_field.sql-28                                    129945              8746 ns/op            2352 B/op         51 allocs/op\nBenchmarkParseSQLFiles/select_with_query_parameter.sql-28                                  33850             36346 ns/op            9936 B/op        209 allocs/op\nBenchmarkParseSQLFiles/select_with_string_expr.sql-28                                     142882              7530 ns/op            1880 B/op         34 allocs/op\nBenchmarkParseSQLFiles/select_with_union_distinct.sql-28                                  147031              9601 ns/op            2352 B/op         47 allocs/op\nBenchmarkParseSQLFiles/select_with_variable.sql-28                                        179158              6669 ns/op            1880 B/op         36 allocs/op\nBenchmarkParseSQLFiles/select_with_window_function.sql-28                                  54925             31320 ns/op            6720 B/op        136 allocs/op\nBenchmarkParseSQLFiles/select_with_placeholder.sql-28                                    196771              5145 ns/op            1272 B/op         26 allocs/op\nBenchmarkParseSQLFiles/set_simple.sql-28                                                  172419              7062 ns/op            2480 B/op         49 allocs/op\nBenchmarkParseComplexQueries/testdata/query/select_with_multi_join.sql-28                  39056             36897 ns/op            8240 B/op        188 allocs/op\nBenchmarkParseComplexQueries/testdata/query/select_with_window_function.sql-28             47629             29916 ns/op            6720 B/op        136 allocs/op\nBenchmarkParseComplexQueries/testdata/query/select_simple_with_with_clause.sql-28                  69210             19731 ns/op            5144 B/op        109 allocs/op\nBenchmarkParseComplexQueries/testdata/query/select_with_left_join.sql-28                           74576             15338 ns/op            3880 B/op         75 allocs/op\nBenchmarkParseComplexQueries/testdata/benchdata/posthog_huge_0.sql-28                                235           6231253 ns/op         1236189 B/op      26696 allocs/op\nBenchmarkParseComplexQueries/testdata/benchdata/posthog_huge_1.sql-28                                279           4438280 ns/op         1043374 B/op      22717 allocs/op\nPASS\nok      github.com/AfterShip/clickhouse-sql-parser/parser       66.547s\n```\n\n## Contact us\n\nFeel free to open an issue or discussion if you have any issues or questions.\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/AfterShip/clickhouse-sql-parser\n\ngo 1.21.0\n\nrequire (\n\tgithub.com/sebdah/goldie/v2 v2.5.3\n\tgithub.com/stretchr/testify v1.8.4\n)\n\nrequire (\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/sergi/go-diff v1.0.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=\ngithub.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=\ngithub.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=\ngithub.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tclickhouse \"github.com/AfterShip/clickhouse-sql-parser/parser\"\n)\n\nconst VERSION = \"0.4.17\"\nconst help = `\nUsage: clickhouse-sql-parser [YOUR SQL STRING] -f [YOUR SQL FILE] -format -beautify\n`\n\nvar options struct {\n\thelp     bool\n\tfile     string\n\tformat   bool\n\tbeautify bool\n\tversion  bool\n}\n\nfunc init() {\n\tflag.BoolVar(&options.format, \"format\", false, \"Print formatted ClickHouse SQL\")\n\tflag.BoolVar(&options.beautify, \"beautify\", false, \"Beautify print the ClickHouse SQL\")\n\tflag.StringVar(&options.file, \"f\", \"\", \"Parse SQL from file\")\n\tflag.BoolVar(&options.help, \"h\", false, \"Print help message\")\n\tflag.BoolVar(&options.version, \"v\", false, \"Print version\")\n}\n\nfunc main() {\n\tflag.Parse()\n\tif options.version {\n\t\tfmt.Println(\"v\" + VERSION)\n\t\tos.Exit(0)\n\t}\n\tif len(os.Args) < 2 || options.help {\n\t\tfmt.Print(help)\n\t\tos.Exit(0)\n\t}\n\n\tvar err error\n\tvar inputBytes []byte\n\tif options.file != \"\" {\n\t\tinputBytes, err = os.ReadFile(options.file)\n\t\tif err != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"read file error: %s\\n\", err.Error())\n\t\t\tos.Exit(1)\n\t\t}\n\t} else {\n\t\tif strings.HasPrefix(os.Args[len(os.Args)-1], \"-\") {\n\t\t\tfmt.Print(help)\n\t\t\tos.Exit(0)\n\t\t}\n\t\tinputBytes = []byte(os.Args[len(os.Args)-1])\n\t}\n\tparser := clickhouse.NewParser(string(inputBytes))\n\tstmts, err := parser.ParseStmts()\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"parse statements error: %s\\n\", err.Error())\n\t\tos.Exit(1)\n\t}\n\tif !options.format && !options.beautify { // print AST\n\t\tbytes, _ := json.MarshalIndent(stmts, \"\", \"  \") // nolint\n\t\tfmt.Println(string(bytes))\n\t} else { // format SQL\n\t\tfor _, stmt := range stmts {\n\t\t\tif options.beautify {\n\t\t\t\tformatter := clickhouse.NewFormatter()\n\t\t\t\tformatter.WithBeautify()\n\t\t\t\tformatter.WriteExpr(stmt)\n\t\t\t\tfmt.Println(formatter.String())\n\t\t\t} else {\n\t\t\t\tfmt.Println(clickhouse.Format(stmt))\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "parser/ast.go",
    "content": "package parser\n\ntype OrderDirection string\n\nconst (\n\tOrderDirectionNone OrderDirection = \"\"\n\tOrderDirectionAsc  OrderDirection = \"ASC\"\n\tOrderDirectionDesc OrderDirection = \"DESC\"\n)\n\ntype Expr interface {\n\tPos() Pos\n\tEnd() Pos\n\tFormatSQL(*Formatter)\n\tAccept(visitor ASTVisitor) error\n}\n\ntype DDL interface {\n\tExpr\n\tType() string\n}\n\ntype SelectItem struct {\n\tExpr Expr\n\t// Please refer: https://clickhouse.com/docs/en/sql-reference/statements/select#select-modifiers\n\tModifiers []*FunctionExpr\n\tAlias     *Ident\n}\n\nfunc (s *SelectItem) Pos() Pos {\n\treturn s.Expr.Pos()\n}\n\nfunc (s *SelectItem) End() Pos {\n\tif s.Alias != nil {\n\t\treturn s.Alias.End()\n\t}\n\tif len(s.Modifiers) > 0 {\n\t\treturn s.Modifiers[len(s.Modifiers)-1].End()\n\t}\n\treturn s.Expr.End()\n}\n\nfunc (s *SelectItem) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, modifier := range s.Modifiers {\n\t\tif err := modifier.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Alias != nil {\n\t\tif err := s.Alias.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSelectItem(s)\n}\n\ntype OperationExpr struct {\n\tOperationPos Pos\n\tKind         TokenKind\n}\n\nfunc (o *OperationExpr) Pos() Pos {\n\treturn o.OperationPos\n}\n\nfunc (o *OperationExpr) End() Pos {\n\treturn o.OperationPos + Pos(len(o.Kind))\n}\n\nfunc (o *OperationExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\treturn visitor.VisitOperationExpr(o)\n}\n\ntype TernaryOperation struct {\n\tCondition Expr\n\tTrueExpr  Expr\n\tFalseExpr Expr\n}\n\nfunc (t *TernaryOperation) Pos() Pos {\n\treturn t.Condition.Pos()\n}\n\nfunc (t *TernaryOperation) End() Pos {\n\treturn t.FalseExpr.End()\n}\n\nfunc (t *TernaryOperation) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.TrueExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := t.FalseExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := t.Condition.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTernaryExpr(t)\n}\n\ntype BinaryOperation struct {\n\tLeftExpr  Expr\n\tOperation TokenKind\n\tRightExpr Expr\n\tHasGlobal bool\n\tHasNot    bool\n}\n\nfunc (p *BinaryOperation) Pos() Pos {\n\treturn p.LeftExpr.Pos()\n}\n\nfunc (p *BinaryOperation) End() Pos {\n\treturn p.RightExpr.End()\n}\n\nfunc (p *BinaryOperation) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tif err := p.LeftExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := p.RightExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitBinaryExpr(p)\n}\n\ntype IndexOperation struct {\n\tObject    Expr\n\tOperation TokenKind\n\tIndex     Expr\n}\n\nfunc (i *IndexOperation) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\tif err := i.Object.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := i.Index.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitIndexOperation(i)\n}\n\nfunc (i *IndexOperation) Pos() Pos {\n\treturn i.Object.Pos()\n}\n\nfunc (i *IndexOperation) End() Pos {\n\treturn i.Index.End()\n}\n\ntype JoinTableExpr struct {\n\tTable        *TableExpr\n\tStatementEnd Pos\n\tSampleRatio  *SampleClause\n\tHasFinal     bool\n}\n\nfunc (j *JoinTableExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(j)\n\tdefer visitor.Leave(j)\n\tif err := j.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif j.SampleRatio != nil {\n\t\treturn j.SampleRatio.Accept(visitor)\n\t}\n\treturn visitor.VisitJoinTableExpr(j)\n}\n\nfunc (j *JoinTableExpr) Pos() Pos {\n\treturn j.Table.Pos()\n}\n\nfunc (j *JoinTableExpr) End() Pos {\n\treturn j.StatementEnd\n}\n\ntype AlterTableClause interface {\n\tExpr\n\tAlterType() string\n}\n\ntype AlterTable struct {\n\tAlterPos        Pos\n\tStatementEnd    Pos\n\tTableIdentifier *TableIdentifier\n\tOnCluster       *ClusterClause\n\tAlterExprs      []AlterTableClause\n}\n\nfunc (a *AlterTable) Pos() Pos {\n\treturn a.AlterPos\n}\n\nfunc (a *AlterTable) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTable) Type() string {\n\treturn \"ALTER TABLE\"\n}\n\nfunc (a *AlterTable) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.TableIdentifier.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.OnCluster != nil {\n\t\tif err := a.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfor _, expr := range a.AlterExprs {\n\t\tif err := expr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTable(a)\n}\n\ntype AlterTableAttachPartition struct {\n\tAttachPos Pos\n\n\tPartition *PartitionClause\n\tFrom      *TableIdentifier\n}\n\nfunc (a *AlterTableAttachPartition) Pos() Pos {\n\treturn a.AttachPos\n}\n\nfunc (a *AlterTableAttachPartition) End() Pos {\n\tif a.From != nil {\n\t\treturn a.From.End()\n\t}\n\treturn a.Partition.End()\n}\n\nfunc (a *AlterTableAttachPartition) AlterType() string {\n\treturn \"ATTACH_PARTITION\"\n}\n\nfunc (a *AlterTableAttachPartition) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Partition.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.From != nil {\n\t\tif err := a.From.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableAttachPartition(a)\n}\n\ntype AlterTableDetachPartition struct {\n\tDetachPos Pos\n\tPartition *PartitionClause\n\tSettings  *SettingsClause\n}\n\nfunc (a *AlterTableDetachPartition) Pos() Pos {\n\treturn a.DetachPos\n}\n\nfunc (a *AlterTableDetachPartition) End() Pos {\n\treturn a.Partition.End()\n}\n\nfunc (a *AlterTableDetachPartition) AlterType() string {\n\treturn \"DETACH_PARTITION\"\n}\n\nfunc (a *AlterTableDetachPartition) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Partition.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.Settings != nil {\n\t\tif err := a.Settings.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableDetachPartition(a)\n}\n\ntype AlterTableDropPartition struct {\n\tDropPos     Pos\n\tHasDetached bool\n\tPartition   *PartitionClause\n\tSettings    *SettingsClause\n}\n\nfunc (a *AlterTableDropPartition) Pos() Pos {\n\treturn a.DropPos\n}\n\nfunc (a *AlterTableDropPartition) End() Pos {\n\tif a.Settings != nil {\n\t\ta.Settings.End()\n\t}\n\treturn a.Partition.End()\n}\n\nfunc (a *AlterTableDropPartition) AlterType() string {\n\treturn \"DROP_PARTITION\"\n}\n\nfunc (a *AlterTableDropPartition) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Partition.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableDropPartition(a)\n}\n\ntype AlterTableMaterializeProjection struct {\n\tMaterializedPos Pos\n\tStatementEnd    Pos\n\tIfExists        bool\n\tProjectionName  *NestedIdentifier\n\tPartition       *PartitionClause\n}\n\nfunc (a *AlterTableMaterializeProjection) Pos() Pos {\n\treturn a.MaterializedPos\n}\n\nfunc (a *AlterTableMaterializeProjection) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableMaterializeProjection) AlterType() string {\n\treturn \"MATERIALIZE_PROJECTION\"\n}\n\nfunc (a *AlterTableMaterializeProjection) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.ProjectionName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.Partition != nil {\n\t\tif err := a.Partition.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableMaterializeProjection(a)\n}\n\ntype AlterTableMaterializeIndex struct {\n\tMaterializedPos Pos\n\tStatementEnd    Pos\n\tIfExists        bool\n\tIndexName       *NestedIdentifier\n\tPartition       *PartitionClause\n}\n\nfunc (a *AlterTableMaterializeIndex) Pos() Pos {\n\treturn a.MaterializedPos\n}\n\nfunc (a *AlterTableMaterializeIndex) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableMaterializeIndex) AlterType() string {\n\treturn \"MATERIALIZE_INDEX\"\n}\n\nfunc (a *AlterTableMaterializeIndex) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.IndexName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.Partition != nil {\n\t\tif err := a.Partition.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableMaterializeIndex(a)\n}\n\ntype AlterTableFreezePartition struct {\n\tFreezePos    Pos\n\tStatementEnd Pos\n\tPartition    *PartitionClause\n}\n\nfunc (a *AlterTableFreezePartition) Pos() Pos {\n\treturn a.FreezePos\n}\n\nfunc (a *AlterTableFreezePartition) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableFreezePartition) AlterType() string {\n\treturn \"FREEZE_PARTITION\"\n}\n\nfunc (a *AlterTableFreezePartition) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif a.Partition != nil {\n\t\tif err := a.Partition.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableFreezePartition(a)\n}\n\ntype AlterTableAddColumn struct {\n\tAddPos       Pos\n\tStatementEnd Pos\n\n\tColumn      *ColumnDef\n\tIfNotExists bool\n\tAfter       *NestedIdentifier\n\tSettings    *SettingsClause\n}\n\nfunc (a *AlterTableAddColumn) Pos() Pos {\n\treturn a.AddPos\n}\n\nfunc (a *AlterTableAddColumn) End() Pos {\n\tif a.Settings != nil {\n\t\treturn a.Settings.End()\n\t}\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableAddColumn) AlterType() string {\n\treturn \"ADD_COLUMN\"\n}\n\nfunc (a *AlterTableAddColumn) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Column.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.After != nil {\n\t\tif err := a.After.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif a.Settings != nil {\n\t\tif err := a.Settings.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableAddColumn(a)\n}\n\ntype AlterTableAddIndex struct {\n\tAddPos       Pos\n\tStatementEnd Pos\n\n\tIndex       *TableIndex\n\tIfNotExists bool\n\tAfter       *NestedIdentifier\n}\n\nfunc (a *AlterTableAddIndex) Pos() Pos {\n\treturn a.AddPos\n}\n\nfunc (a *AlterTableAddIndex) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableAddIndex) AlterType() string {\n\treturn \"ADD_INDEX\"\n}\n\nfunc (a *AlterTableAddIndex) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Index.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.After != nil {\n\t\tif err := a.After.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableAddIndex(a)\n}\n\ntype ProjectionOrderByClause struct {\n\tOrderByPos Pos\n\tColumns    *ColumnExprList\n}\n\nfunc (p *ProjectionOrderByClause) Pos() Pos {\n\treturn p.OrderByPos\n}\n\nfunc (p *ProjectionOrderByClause) End() Pos {\n\treturn p.Columns.End()\n}\n\nfunc (p *ProjectionOrderByClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\treturn visitor.VisitProjectionOrderBy(p)\n}\n\ntype ProjectionSelectStmt struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tWith          *WithClause\n\tSelectColumns *ColumnExprList\n\tGroupBy       *GroupByClause\n\tOrderBy       *ProjectionOrderByClause\n}\n\nfunc (p *ProjectionSelectStmt) Pos() Pos {\n\treturn p.LeftParenPos\n\n}\n\nfunc (p *ProjectionSelectStmt) End() Pos {\n\treturn p.RightParenPos\n}\n\nfunc (p *ProjectionSelectStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tif p.With != nil {\n\t\tif err := p.With.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := p.SelectColumns.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif p.GroupBy != nil {\n\t\tif err := p.GroupBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif p.OrderBy != nil {\n\t\tif err := p.OrderBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitProjectionSelect(p)\n}\n\ntype TableProjection struct {\n\tIncludeProjectionKeyword bool\n\tProjectionPos            Pos\n\tIdentifier               *NestedIdentifier\n\tSelect                   *ProjectionSelectStmt\n}\n\nfunc (t *TableProjection) Pos() Pos {\n\treturn t.ProjectionPos\n}\n\nfunc (t *TableProjection) End() Pos {\n\treturn t.Select.End()\n}\n\nfunc (t *TableProjection) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Identifier.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := t.Select.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTableProjection(t)\n}\n\ntype AlterTableAddProjection struct {\n\tAddPos       Pos\n\tStatementEnd Pos\n\n\tIfNotExists     bool\n\tTableProjection *TableProjection\n\tAfter           *NestedIdentifier\n}\n\nfunc (a *AlterTableAddProjection) Pos() Pos {\n\treturn a.AddPos\n}\n\nfunc (a *AlterTableAddProjection) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableAddProjection) AlterType() string {\n\treturn \"ADD_PROJECTION\"\n}\n\nfunc (a *AlterTableAddProjection) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.TableProjection.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.After != nil {\n\t\tif err := a.After.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableAddProjection(a)\n}\n\ntype AlterTableDropColumn struct {\n\tDropPos    Pos\n\tColumnName *NestedIdentifier\n\tIfExists   bool\n}\n\nfunc (a *AlterTableDropColumn) Pos() Pos {\n\treturn a.DropPos\n}\n\nfunc (a *AlterTableDropColumn) End() Pos {\n\treturn a.ColumnName.End()\n}\n\nfunc (a *AlterTableDropColumn) AlterType() string {\n\treturn \"DROP_COLUMN\"\n}\n\nfunc (a *AlterTableDropColumn) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.ColumnName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableDropColumn(a)\n}\n\ntype AlterTableDropIndex struct {\n\tDropPos   Pos\n\tIndexName *NestedIdentifier\n\tIfExists  bool\n}\n\nfunc (a *AlterTableDropIndex) Pos() Pos {\n\treturn a.DropPos\n}\n\nfunc (a *AlterTableDropIndex) End() Pos {\n\treturn a.IndexName.End()\n}\n\nfunc (a *AlterTableDropIndex) AlterType() string {\n\treturn \"DROP_INDEX\"\n}\n\nfunc (a *AlterTableDropIndex) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.IndexName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableDropIndex(a)\n}\n\ntype AlterTableDropProjection struct {\n\tDropPos        Pos\n\tProjectionName *NestedIdentifier\n\tIfExists       bool\n}\n\nfunc (a *AlterTableDropProjection) Pos() Pos {\n\treturn a.DropPos\n}\n\nfunc (a *AlterTableDropProjection) End() Pos {\n\treturn a.ProjectionName.End()\n}\n\nfunc (a *AlterTableDropProjection) AlterType() string {\n\treturn \"DROP_PROJECTION\"\n}\n\nfunc (a *AlterTableDropProjection) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.ProjectionName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableDropProjection(a)\n}\n\ntype AlterTableRemoveTTL struct {\n\tRemovePos    Pos\n\tStatementEnd Pos\n}\n\nfunc (a *AlterTableRemoveTTL) Pos() Pos {\n\treturn a.RemovePos\n}\n\nfunc (a *AlterTableRemoveTTL) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableRemoveTTL) AlterType() string {\n\treturn \"REMOVE_TTL\"\n}\n\nfunc (a *AlterTableRemoveTTL) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\treturn visitor.VisitAlterTableRemoveTTL(a)\n}\n\ntype AlterTableClearColumn struct {\n\tClearPos     Pos\n\tStatementEnd Pos\n\n\tIfExists      bool\n\tColumnName    *NestedIdentifier\n\tPartitionExpr *PartitionClause\n}\n\nfunc (a *AlterTableClearColumn) Pos() Pos {\n\treturn a.ClearPos\n}\n\nfunc (a *AlterTableClearColumn) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableClearColumn) AlterType() string {\n\treturn \"CLEAR_COLUMN\"\n}\n\nfunc (a *AlterTableClearColumn) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.ColumnName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.PartitionExpr != nil {\n\t\tif err := a.PartitionExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableClearColumn(a)\n}\n\ntype AlterTableClearIndex struct {\n\tClearPos     Pos\n\tStatementEnd Pos\n\n\tIfExists      bool\n\tIndexName     *NestedIdentifier\n\tPartitionExpr *PartitionClause\n}\n\nfunc (a *AlterTableClearIndex) Pos() Pos {\n\treturn a.ClearPos\n}\n\nfunc (a *AlterTableClearIndex) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableClearIndex) AlterType() string {\n\treturn \"CLEAR_INDEX\"\n}\n\nfunc (a *AlterTableClearIndex) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.IndexName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.PartitionExpr != nil {\n\t\tif err := a.PartitionExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableClearIndex(a)\n}\n\ntype AlterTableClearProjection struct {\n\tClearPos     Pos\n\tStatementEnd Pos\n\n\tIfExists       bool\n\tProjectionName *NestedIdentifier\n\tPartitionExpr  *PartitionClause\n}\n\nfunc (a *AlterTableClearProjection) Pos() Pos {\n\treturn a.ClearPos\n}\n\nfunc (a *AlterTableClearProjection) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableClearProjection) AlterType() string {\n\treturn \"CLEAR_PROJECTION\"\n}\n\nfunc (a *AlterTableClearProjection) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.ProjectionName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.PartitionExpr != nil {\n\t\tif err := a.PartitionExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableClearProjection(a)\n}\n\ntype AlterTableRenameColumn struct {\n\tRenamePos Pos\n\n\tIfExists      bool\n\tOldColumnName *NestedIdentifier\n\tNewColumnName *NestedIdentifier\n}\n\nfunc (a *AlterTableRenameColumn) Pos() Pos {\n\treturn a.RenamePos\n}\n\nfunc (a *AlterTableRenameColumn) End() Pos {\n\treturn a.NewColumnName.End()\n}\n\nfunc (a *AlterTableRenameColumn) AlterType() string {\n\treturn \"RENAME_COLUMN\"\n}\n\nfunc (a *AlterTableRenameColumn) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.OldColumnName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := a.NewColumnName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableRenameColumn(a)\n}\n\ntype AlterTableModifyQuery struct {\n\tModifyPos    Pos\n\tStatementEnd Pos\n\tSelectExpr   *SelectQuery\n}\n\nfunc (a *AlterTableModifyQuery) Pos() Pos {\n\treturn a.ModifyPos\n}\n\nfunc (a *AlterTableModifyQuery) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableModifyQuery) AlterType() string {\n\treturn \"MODIFY_QUERY\"\n}\n\nfunc (a *AlterTableModifyQuery) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.SelectExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableModifyQuery(a)\n}\n\ntype AlterTableModifyTTL struct {\n\tModifyPos    Pos\n\tStatementEnd Pos\n\tTTL          *TTLClause\n}\n\nfunc (a *AlterTableModifyTTL) Pos() Pos {\n\treturn a.ModifyPos\n}\n\nfunc (a *AlterTableModifyTTL) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableModifyTTL) AlterType() string {\n\treturn \"MODIFY_TTL\"\n}\n\nfunc (a *AlterTableModifyTTL) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.TTL.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableModifyTTL(a)\n}\n\ntype AlterTableModifyColumn struct {\n\tModifyPos    Pos\n\tStatementEnd Pos\n\n\tIfExists           bool\n\tColumn             *ColumnDef\n\tRemovePropertyType *RemovePropertyType\n}\n\nfunc (a *AlterTableModifyColumn) Pos() Pos {\n\treturn a.ModifyPos\n}\n\nfunc (a *AlterTableModifyColumn) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableModifyColumn) AlterType() string {\n\treturn \"MODIFY_COLUMN\"\n}\n\nfunc (a *AlterTableModifyColumn) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Column.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif a.RemovePropertyType != nil {\n\t\tif err := a.RemovePropertyType.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableModifyColumn(a)\n}\n\ntype AlterTableModifySetting struct {\n\tModifyPos    Pos\n\tStatementEnd Pos\n\tSettings     []*SettingExpr\n}\n\nfunc (a *AlterTableModifySetting) Pos() Pos {\n\treturn a.ModifyPos\n}\n\nfunc (a *AlterTableModifySetting) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableModifySetting) AlterType() string {\n\treturn \"MODIFY_SETTING\"\n}\n\nfunc (a *AlterTableModifySetting) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tfor _, setting := range a.Settings {\n\t\tif err := setting.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableModifySetting(a)\n}\n\ntype AlterTableResetSetting struct {\n\tResetPos     Pos\n\tStatementEnd Pos\n\tSettings     []*Ident\n}\n\nfunc (a *AlterTableResetSetting) Pos() Pos {\n\treturn a.ResetPos\n}\n\nfunc (a *AlterTableResetSetting) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableResetSetting) AlterType() string {\n\treturn \"RESET_SETTING\"\n}\n\nfunc (a *AlterTableResetSetting) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tfor _, setting := range a.Settings {\n\t\tif err := setting.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterTableResetSetting(a)\n}\n\ntype AlterTableReplacePartition struct {\n\tReplacePos Pos\n\tPartition  *PartitionClause\n\tTable      *TableIdentifier\n}\n\nfunc (a *AlterTableReplacePartition) Pos() Pos {\n\treturn a.ReplacePos\n}\n\nfunc (a *AlterTableReplacePartition) End() Pos {\n\treturn a.Table.End()\n}\n\nfunc (a *AlterTableReplacePartition) AlterType() string {\n\treturn \"REPLACE_PARTITION\"\n}\n\nfunc (a *AlterTableReplacePartition) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Partition.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := a.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableReplacePartition(a)\n}\n\ntype AlterTableDelete struct {\n\tDeletePos    Pos\n\tStatementEnd Pos\n\tWhereClause  Expr\n}\n\nfunc (a *AlterTableDelete) Pos() Pos {\n\treturn a.DeletePos\n}\n\nfunc (a *AlterTableDelete) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableDelete) AlterType() string {\n\treturn \"DELETE\"\n}\n\nfunc (a *AlterTableDelete) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.WhereClause.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableDelete(a)\n}\n\ntype AlterTableUpdate struct {\n\tUpdatePos    Pos\n\tStatementEnd Pos\n\tAssignments  []*UpdateAssignment\n\tInPartition  *PartitionClause\n\tWhereClause  Expr\n}\n\nfunc (a *AlterTableUpdate) Pos() Pos {\n\treturn a.UpdatePos\n}\n\nfunc (a *AlterTableUpdate) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterTableUpdate) AlterType() string {\n\treturn \"UPDATE\"\n}\n\nfunc (a *AlterTableUpdate) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tfor _, assignment := range a.Assignments {\n\t\tif err := assignment.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif a.InPartition != nil {\n\t\tif err := a.InPartition.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := a.WhereClause.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAlterTableUpdate(a)\n}\n\ntype UpdateAssignment struct {\n\tAssignmentPos Pos\n\tColumn        *NestedIdentifier\n\tExpr          Expr\n}\n\nfunc (u *UpdateAssignment) Pos() Pos {\n\treturn u.AssignmentPos\n}\n\nfunc (u *UpdateAssignment) End() Pos {\n\treturn u.Expr.End()\n}\n\nfunc (u *UpdateAssignment) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(u)\n\tdefer visitor.Leave(u)\n\tif err := u.Column.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := u.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitUpdateAssignment(u)\n}\n\ntype RemovePropertyType struct {\n\tRemovePos Pos\n\n\tPropertyType Expr\n}\n\nfunc (a *RemovePropertyType) Pos() Pos {\n\treturn a.RemovePos\n}\n\nfunc (a *RemovePropertyType) End() Pos {\n\treturn a.PropertyType.End()\n}\n\nfunc (a *RemovePropertyType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.PropertyType.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitRemovePropertyType(a)\n}\n\ntype TableIndex struct {\n\tIndexPos Pos\n\n\tName        *NestedIdentifier\n\tColumnExpr  *ColumnExpr\n\tColumnType  Expr\n\tGranularity *NumberLiteral\n}\n\nfunc (a *TableIndex) Pos() Pos {\n\treturn a.IndexPos\n}\n\nfunc (a *TableIndex) End() Pos {\n\treturn a.Granularity.End()\n}\n\nfunc (a *TableIndex) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := a.ColumnExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := a.ColumnType.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := a.Granularity.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTableIndex(a)\n}\n\ntype Ident struct {\n\tName      string\n\tQuoteType int\n\tNamePos   Pos\n\tNameEnd   Pos\n}\n\nfunc (i *Ident) Pos() Pos {\n\treturn i.NamePos\n}\n\nfunc (i *Ident) End() Pos {\n\treturn i.NameEnd\n}\n\nfunc (i *Ident) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\treturn visitor.VisitIdent(i)\n}\n\ntype UUID struct {\n\tValue *StringLiteral\n}\n\nfunc (u *UUID) Pos() Pos {\n\treturn u.Value.LiteralPos\n}\n\nfunc (u *UUID) End() Pos {\n\treturn u.Value.LiteralEnd\n}\n\nfunc (u *UUID) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(u)\n\tdefer visitor.Leave(u)\n\treturn visitor.VisitUUID(u)\n}\n\ntype CreateDatabase struct {\n\tCreatePos    Pos // position of CREATE keyword\n\tStatementEnd Pos\n\tName         Expr\n\tIfNotExists  bool // true if 'IF NOT EXISTS' is specified\n\tOnCluster    *ClusterClause\n\tEngine       *EngineExpr\n\tComment      *StringLiteral\n}\n\nfunc (c *CreateDatabase) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateDatabase) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateDatabase) Type() string {\n\treturn \"DATABASE\"\n}\n\nfunc (c *CreateDatabase) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Engine != nil {\n\t\tif err := c.Engine.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateDatabase(c)\n}\n\ntype CreateTable struct {\n\tCreatePos     Pos // position of CREATE|ATTACH keyword\n\tStatementEnd  Pos\n\tOrReplace     bool\n\tName          *TableIdentifier\n\tIfNotExists   bool\n\tUUID          *UUID\n\tOnCluster     *ClusterClause\n\tTableSchema   *TableSchemaClause\n\tEngine        *EngineExpr\n\tSubQuery      *SubQuery\n\tTableFunction *TableFunctionExpr\n\tHasTemporary  bool\n\tComment       *StringLiteral\n}\n\nfunc (c *CreateTable) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateTable) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateTable) Type() string {\n\treturn \"CREATE TABLE\"\n}\n\nfunc (c *CreateTable) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.UUID != nil {\n\t\tif err := c.UUID.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.TableSchema != nil {\n\t\tif err := c.TableSchema.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Engine != nil {\n\t\tif err := c.Engine.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.SubQuery != nil {\n\t\tif err := c.SubQuery.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.TableFunction != nil {\n\t\tif err := c.TableFunction.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateTable(c)\n}\n\ntype CreateMaterializedView struct {\n\tCreatePos    Pos // position of CREATE|ATTACH keyword\n\tStatementEnd Pos\n\tName         *TableIdentifier\n\tIfNotExists  bool\n\tOnCluster    *ClusterClause\n\tRefresh      *RefreshExpr\n\tRandomizeFor *IntervalExpr\n\tDependsOn    []*TableIdentifier\n\tSettings     *SettingsClause\n\tHasAppend    bool\n\tEngine       *EngineExpr\n\tHasEmpty     bool\n\tDestination  *DestinationClause\n\tSubQuery     *SubQuery\n\tPopulate     bool\n\tComment      *StringLiteral\n\tDefiner      *Ident\n\tSQLSecurity  string\n}\n\nfunc (c *CreateMaterializedView) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateMaterializedView) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateMaterializedView) Type() string {\n\treturn \"MATERIALIZED_VIEW\"\n}\n\nfunc (c *CreateMaterializedView) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Refresh != nil {\n\t\tif err := c.Refresh.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.RandomizeFor != nil {\n\t\tif err := c.RandomizeFor.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.DependsOn != nil {\n\t\tfor _, dep := range c.DependsOn {\n\t\t\tif err := dep.Accept(visitor); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tif c.Settings != nil {\n\t\tif err := c.Settings.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Engine != nil {\n\t\tif err := c.Engine.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Destination != nil {\n\t\tif err := c.Destination.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif c.Destination.TableSchema != nil {\n\t\t\tif err := c.Destination.TableSchema.Accept(visitor); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tif c.SubQuery != nil {\n\t\tif err := c.SubQuery.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Definer != nil {\n\t\tif err := c.Definer.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Comment != nil {\n\t\tif err := c.Comment.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateMaterializedView(c)\n}\n\ntype CreateView struct {\n\tCreatePos    Pos // position of CREATE|ATTACH keyword\n\tStatementEnd Pos\n\tOrReplace    bool\n\tName         *TableIdentifier\n\tIfNotExists  bool\n\tUUID         *UUID\n\tOnCluster    *ClusterClause\n\tTableSchema  *TableSchemaClause\n\tComment      *StringLiteral\n\tSubQuery     *SubQuery\n}\n\nfunc (c *CreateView) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateView) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateView) Type() string {\n\treturn \"VIEW\"\n}\n\nfunc (c *CreateView) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.UUID != nil {\n\t\tif err := c.UUID.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.TableSchema != nil {\n\t\tif err := c.TableSchema.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Comment != nil {\n\t\tif err := c.Comment.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.SubQuery != nil {\n\t\tif err := c.SubQuery.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateView(c)\n}\n\ntype CreateFunction struct {\n\tCreatePos    Pos\n\tOrReplace    bool\n\tIfNotExists  bool\n\tFunctionName *Ident\n\tOnCluster    *ClusterClause\n\tParams       *ParamExprList\n\tExpr         Expr\n}\n\nfunc (c *CreateFunction) Type() string {\n\treturn \"FUNCTION\"\n}\n\nfunc (c *CreateFunction) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateFunction) End() Pos {\n\treturn c.Expr.End()\n}\n\nfunc (c *CreateFunction) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.FunctionName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := c.Params.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := c.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitCreateFunction(c)\n}\n\ntype RoleName struct {\n\tName      Expr\n\tScope     *StringLiteral\n\tOnCluster *ClusterClause\n}\n\nfunc (r *RoleName) Pos() Pos {\n\treturn r.Name.Pos()\n}\n\nfunc (r *RoleName) End() Pos {\n\tif r.Scope != nil {\n\t\treturn r.Scope.End()\n\t}\n\tif r.OnCluster != nil {\n\t\treturn r.OnCluster.End()\n\t}\n\treturn r.Name.End()\n}\n\nfunc (r *RoleName) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(r)\n\tdefer visitor.Leave(r)\n\tif err := r.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif r.Scope != nil {\n\t\tif err := r.Scope.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif r.OnCluster != nil {\n\t\tif err := r.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitRoleName(r)\n}\n\ntype SettingPair struct {\n\tName      *Ident\n\tOperation TokenKind\n\tValue     Expr\n}\n\nfunc (s *SettingPair) Pos() Pos {\n\treturn s.Name.NamePos\n}\n\nfunc (s *SettingPair) End() Pos {\n\treturn s.Value.End()\n}\n\nfunc (s *SettingPair) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif s.Value != nil {\n\t\tif err := s.Value.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSettingPair(s)\n}\n\ntype RoleSetting struct {\n\tSettingPairs []*SettingPair\n\tModifier     *Ident\n}\n\nfunc (r *RoleSetting) Pos() Pos {\n\tif len(r.SettingPairs) > 0 {\n\t\treturn r.SettingPairs[0].Pos()\n\t}\n\treturn r.Modifier.NamePos\n}\n\nfunc (r *RoleSetting) End() Pos {\n\tif r.Modifier != nil {\n\t\treturn r.Modifier.NameEnd\n\t}\n\treturn r.SettingPairs[len(r.SettingPairs)-1].End()\n}\n\nfunc (r *RoleSetting) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(r)\n\tdefer visitor.Leave(r)\n\tfor _, settingPair := range r.SettingPairs {\n\t\tif err := settingPair.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif r.Modifier != nil {\n\t\tif err := r.Modifier.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitRoleSetting(r)\n}\n\ntype CreateRole struct {\n\tCreatePos         Pos\n\tStatementEnd      Pos\n\tIfNotExists       bool\n\tOrReplace         bool\n\tRoleNames         []*RoleName\n\tAccessStorageType *Ident\n\tSettings          []*RoleSetting\n}\n\nfunc (c *CreateRole) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateRole) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateRole) Type() string {\n\treturn \"ROLE\"\n}\n\nfunc (c *CreateRole) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tfor _, roleName := range c.RoleNames {\n\t\tif err := roleName.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.AccessStorageType != nil {\n\t\tif err := c.AccessStorageType.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, setting := range c.Settings {\n\t\tif err := setting.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateRole(c)\n}\n\ntype AuthenticationClause struct {\n\tAuthPos       Pos\n\tAuthEnd       Pos\n\tNotIdentified bool\n\tAuthType      string // \"no_password\", \"plaintext_password\", \"sha256_password\", etc.\n\tAuthValue     *StringLiteral\n\tLdapServer    *StringLiteral\n\tKerberosRealm *StringLiteral\n\tIsKerberos    bool\n}\n\nfunc (a *AuthenticationClause) Pos() Pos {\n\treturn a.AuthPos\n}\n\nfunc (a *AuthenticationClause) End() Pos {\n\treturn a.AuthEnd\n}\n\nfunc (a *AuthenticationClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif a.AuthValue != nil {\n\t\tif err := a.AuthValue.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif a.LdapServer != nil {\n\t\tif err := a.LdapServer.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif a.KerberosRealm != nil {\n\t\tif err := a.KerberosRealm.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAuthenticationClause(a)\n}\n\ntype HostClause struct {\n\tHostPos   Pos\n\tHostEnd   Pos\n\tHostType  string // \"LOCAL\", \"NAME\", \"REGEXP\", \"IP\", \"LIKE\", \"ANY\", \"NONE\"\n\tHostValue *StringLiteral\n}\n\nfunc (h *HostClause) Pos() Pos {\n\treturn h.HostPos\n}\n\nfunc (h *HostClause) End() Pos {\n\treturn h.HostEnd\n}\n\nfunc (h *HostClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(h)\n\tdefer visitor.Leave(h)\n\tif h.HostValue != nil {\n\t\tif err := h.HostValue.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitHostClause(h)\n}\n\ntype DefaultRoleClause struct {\n\tDefaultPos Pos\n\tDefaultEnd Pos\n\tRoles      []*RoleName\n\tNone       bool\n}\n\nfunc (d *DefaultRoleClause) Pos() Pos {\n\treturn d.DefaultPos\n}\n\nfunc (d *DefaultRoleClause) End() Pos {\n\treturn d.DefaultEnd\n}\n\nfunc (d *DefaultRoleClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tfor _, role := range d.Roles {\n\t\tif err := role.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDefaultRoleClause(d)\n}\n\ntype GranteesClause struct {\n\tGranteesPos Pos\n\tGranteesEnd Pos\n\tGrantees    []*RoleName\n\tExceptUsers []*RoleName\n\tAny         bool\n\tNone        bool\n}\n\nfunc (g *GranteesClause) Pos() Pos {\n\treturn g.GranteesPos\n}\n\nfunc (g *GranteesClause) End() Pos {\n\treturn g.GranteesEnd\n}\n\nfunc (g *GranteesClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(g)\n\tdefer visitor.Leave(g)\n\tfor _, grantee := range g.Grantees {\n\t\tif err := grantee.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, except := range g.ExceptUsers {\n\t\tif err := except.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitGranteesClause(g)\n}\n\ntype CreateUser struct {\n\tCreatePos       Pos\n\tStatementEnd    Pos\n\tIfNotExists     bool\n\tOrReplace       bool\n\tUserNames       []*RoleName\n\tAuthentication  *AuthenticationClause\n\tValidUntil      *StringLiteral\n\tHosts           []*HostClause\n\tDefaultRole     *DefaultRoleClause\n\tDefaultDatabase *Ident\n\tDefaultDbNone   bool\n\tGrantees        *GranteesClause\n\tSettings        []*RoleSetting\n}\n\nfunc (c *CreateUser) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateUser) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateUser) Type() string {\n\treturn \"USER\"\n}\n\nfunc (c *CreateUser) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tfor _, userName := range c.UserNames {\n\t\tif err := userName.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Authentication != nil {\n\t\tif err := c.Authentication.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.ValidUntil != nil {\n\t\tif err := c.ValidUntil.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, host := range c.Hosts {\n\t\tif err := host.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.DefaultRole != nil {\n\t\tif err := c.DefaultRole.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.DefaultDatabase != nil {\n\t\tif err := c.DefaultDatabase.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Grantees != nil {\n\t\tif err := c.Grantees.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, setting := range c.Settings {\n\t\tif err := setting.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateUser(c)\n}\n\ntype AlterRole struct {\n\tAlterPos        Pos\n\tStatementEnd    Pos\n\tIfExists        bool\n\tRoleRenamePairs []*RoleRenamePair\n\tSettings        []*RoleSetting\n}\n\nfunc (a *AlterRole) Pos() Pos {\n\treturn a.AlterPos\n}\n\nfunc (a *AlterRole) End() Pos {\n\treturn a.StatementEnd\n}\n\nfunc (a *AlterRole) Type() string {\n\treturn \"ROLE\"\n}\n\nfunc (a *AlterRole) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tfor _, roleRenamePair := range a.RoleRenamePairs {\n\t\tif err := roleRenamePair.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, setting := range a.Settings {\n\t\tif err := setting.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitAlterRole(a)\n}\n\ntype RoleRenamePair struct {\n\tRoleName     *RoleName\n\tNewName      Expr\n\tStatementEnd Pos\n}\n\nfunc (r *RoleRenamePair) Pos() Pos {\n\treturn r.RoleName.Pos()\n}\n\nfunc (r *RoleRenamePair) End() Pos {\n\treturn r.StatementEnd\n}\n\nfunc (r *RoleRenamePair) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(r)\n\tdefer visitor.Leave(r)\n\tif err := r.RoleName.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif r.NewName != nil {\n\t\tif err := r.NewName.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitRoleRenamePair(r)\n}\n\ntype DestinationClause struct {\n\tToPos           Pos\n\tTableIdentifier *TableIdentifier\n\tTableSchema     *TableSchemaClause\n}\n\nfunc (d *DestinationClause) Pos() Pos {\n\treturn d.ToPos\n}\n\nfunc (d *DestinationClause) End() Pos {\n\treturn d.TableIdentifier.End()\n}\n\nfunc (d *DestinationClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.TableIdentifier.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitDestinationExpr(d)\n}\n\ntype ConstraintClause struct {\n\tConstraintPos Pos\n\tConstraint    *Ident\n\tExpr          Expr\n}\n\nfunc (c *ConstraintClause) Pos() Pos {\n\treturn c.ConstraintPos\n}\n\nfunc (c *ConstraintClause) End() Pos {\n\treturn c.Expr.End()\n}\n\nfunc (c *ConstraintClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Constraint.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := c.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitConstraintExpr(c)\n}\n\ntype NullLiteral struct {\n\tNullPos Pos\n}\n\nfunc (n *NullLiteral) Pos() Pos {\n\treturn n.NullPos\n}\n\nfunc (n *NullLiteral) End() Pos {\n\treturn n.NullPos + 4\n}\n\nfunc (n *NullLiteral) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\treturn visitor.VisitNullLiteral(n)\n}\n\ntype NotNullLiteral struct {\n\tNotPos      Pos\n\tNullLiteral *NullLiteral\n}\n\nfunc (n *NotNullLiteral) Pos() Pos {\n\treturn n.NotPos\n}\n\nfunc (n *NotNullLiteral) End() Pos {\n\treturn n.NullLiteral.End()\n}\n\nfunc (n *NotNullLiteral) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.NullLiteral.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitNotNullLiteral(n)\n}\n\ntype NestedIdentifier struct {\n\tIdent    *Ident\n\tDotIdent *Ident\n}\n\nfunc (n *NestedIdentifier) Pos() Pos {\n\treturn n.Ident.Pos()\n}\n\nfunc (n *NestedIdentifier) End() Pos {\n\tif n.DotIdent != nil {\n\t\treturn n.DotIdent.End()\n\t}\n\treturn n.Ident.End()\n}\n\nfunc (n *NestedIdentifier) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Ident.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif n.DotIdent != nil {\n\t\tif err := n.DotIdent.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitNestedIdentifier(n)\n}\n\ntype Path struct {\n\tFields []*Ident\n}\n\nfunc (p *Path) Pos() Pos {\n\tif len(p.Fields) > 0 {\n\t\treturn p.Fields[0].Pos()\n\t}\n\treturn 0\n}\n\nfunc (p *Path) End() Pos {\n\tif len(p.Fields) > 0 {\n\t\treturn p.Fields[len(p.Fields)-1].End()\n\t}\n\treturn 0\n}\n\nfunc (p *Path) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tfor _, ident := range p.Fields {\n\t\tif err := ident.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitPath(p)\n}\n\ntype TableIdentifier struct {\n\tDatabase *Ident\n\tTable    *Ident\n}\n\nfunc (t *TableIdentifier) Pos() Pos {\n\tif t.Database != nil {\n\t\treturn t.Database.Pos()\n\t}\n\treturn t.Table.Pos()\n}\n\nfunc (t *TableIdentifier) End() Pos {\n\treturn t.Table.End()\n}\n\nfunc (t *TableIdentifier) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif t.Database != nil {\n\t\tif err := t.Database.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := t.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTableIdentifier(t)\n}\n\ntype TableSchemaClause struct {\n\tSchemaPos     Pos\n\tSchemaEnd     Pos\n\tColumns       []Expr\n\tAliasTable    *TableIdentifier\n\tTableFunction *TableFunctionExpr\n}\n\nfunc (t *TableSchemaClause) Pos() Pos {\n\treturn t.SchemaPos\n}\n\nfunc (t *TableSchemaClause) End() Pos {\n\treturn t.SchemaEnd\n}\n\nfunc (t *TableSchemaClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tfor _, column := range t.Columns {\n\t\tif err := column.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif t.AliasTable != nil {\n\t\tif err := t.AliasTable.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif t.TableFunction != nil {\n\t\tif err := t.TableFunction.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTableSchemaExpr(t)\n}\n\ntype TableArgListExpr struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tArgs          []Expr\n}\n\nfunc (t *TableArgListExpr) Pos() Pos {\n\treturn t.LeftParenPos\n}\n\nfunc (t *TableArgListExpr) End() Pos {\n\treturn t.RightParenPos\n}\n\nfunc (t *TableArgListExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tfor _, arg := range t.Args {\n\t\tif err := arg.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTableArgListExpr(t)\n}\n\ntype TableFunctionExpr struct {\n\tName Expr\n\tArgs *TableArgListExpr\n}\n\nfunc (t *TableFunctionExpr) Pos() Pos {\n\treturn t.Name.Pos()\n}\n\nfunc (t *TableFunctionExpr) End() Pos {\n\treturn t.Args.End()\n}\n\nfunc (t *TableFunctionExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := t.Args.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTableFunctionExpr(t)\n}\n\ntype ClusterClause struct {\n\tOnPos Pos\n\tExpr  Expr\n}\n\nfunc (o *ClusterClause) Pos() Pos {\n\treturn o.OnPos\n}\n\nfunc (o *ClusterClause) End() Pos {\n\treturn o.Expr.End()\n}\n\nfunc (o *ClusterClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\tif err := o.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitOnClusterExpr(o)\n}\n\ntype PartitionClause struct {\n\tPartitionPos Pos\n\tExpr         Expr\n\tID           *StringLiteral\n\tAll          bool\n}\n\nfunc (p *PartitionClause) Pos() Pos {\n\treturn p.PartitionPos\n}\n\nfunc (p *PartitionClause) End() Pos {\n\tif p.ID != nil {\n\t\treturn p.ID.LiteralEnd\n\t}\n\treturn p.Expr.End()\n}\n\nfunc (p *PartitionClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tif p.Expr != nil {\n\t\tif err := p.Expr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif p.ID != nil {\n\t\tif err := p.ID.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitPartitionExpr(p)\n}\n\ntype PartitionByClause struct {\n\tPartitionPos Pos\n\tExpr         Expr\n}\n\nfunc (p *PartitionByClause) Pos() Pos {\n\treturn p.PartitionPos\n}\n\nfunc (p *PartitionByClause) End() Pos {\n\treturn p.Expr.End()\n}\n\nfunc (p *PartitionByClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tif err := p.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitPartitionByExpr(p)\n}\n\ntype PrimaryKeyClause struct {\n\tPrimaryPos Pos\n\tExpr       Expr\n}\n\nfunc (p *PrimaryKeyClause) Pos() Pos {\n\treturn p.PrimaryPos\n}\n\nfunc (p *PrimaryKeyClause) End() Pos {\n\treturn p.Expr.End()\n}\n\nfunc (p *PrimaryKeyClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tif err := p.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitPrimaryKeyExpr(p)\n}\n\ntype SampleByClause struct {\n\tSamplePos Pos\n\tExpr      Expr\n}\n\nfunc (s *SampleByClause) Pos() Pos {\n\treturn s.SamplePos\n}\n\nfunc (s *SampleByClause) End() Pos {\n\treturn s.Expr.End()\n}\n\nfunc (s *SampleByClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitSampleByExpr(s)\n}\n\ntype TTLPolicyRuleAction struct {\n\tActionPos Pos\n\tActionEnd Pos\n\tAction    string\n\tCodec     *CompressionCodec\n}\n\nfunc (t *TTLPolicyRuleAction) Pos() Pos {\n\treturn t.ActionPos\n}\n\nfunc (t *TTLPolicyRuleAction) End() Pos {\n\tif t.Codec != nil {\n\t\treturn t.Codec.End()\n\t}\n\treturn t.ActionEnd\n}\n\nfunc (t *TTLPolicyRuleAction) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif t.Codec != nil {\n\t\tif err := t.Codec.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTTLPolicyItemAction(t)\n}\n\ntype RefreshExpr struct {\n\tRefreshPos Pos\n\tFrequency  string // EVERY|AFTER\n\tInterval   *IntervalExpr\n\tOffset     *IntervalExpr\n}\n\nfunc (r *RefreshExpr) Pos() Pos {\n\treturn r.RefreshPos\n}\n\nfunc (r *RefreshExpr) End() Pos {\n\tif r.Offset != nil {\n\t\treturn r.Offset.End()\n\t}\n\treturn r.Interval.End()\n}\n\nfunc (r *RefreshExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(r)\n\tdefer visitor.Leave(r)\n\tif r.Interval != nil {\n\t\tif err := r.Interval.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif r.Offset != nil {\n\t\tif err := r.Offset.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitRefreshExpr(r)\n}\n\ntype TTLPolicyRule struct {\n\tRulePos  Pos\n\tToVolume *StringLiteral\n\tToDisk   *StringLiteral\n\tAction   *TTLPolicyRuleAction\n}\n\nfunc (t *TTLPolicyRule) Pos() Pos {\n\treturn t.RulePos\n}\n\nfunc (t *TTLPolicyRule) End() Pos {\n\tif t.Action != nil {\n\t\treturn t.Action.End()\n\t}\n\tif t.ToDisk != nil {\n\t\treturn t.ToDisk.LiteralEnd\n\t}\n\treturn t.ToVolume.LiteralEnd\n}\n\nfunc (t *TTLPolicyRule) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif t.ToVolume != nil {\n\t\tif err := t.ToVolume.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif t.ToDisk != nil {\n\t\tif err := t.ToDisk.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTTLPolicyRule(t)\n}\n\ntype TTLPolicy struct {\n\tItem    *TTLPolicyRule\n\tWhere   *WhereClause\n\tGroupBy *GroupByClause\n}\n\nfunc (t *TTLPolicy) Pos() Pos {\n\tif t.Item != nil {\n\t\treturn t.Item.Pos()\n\t}\n\tif t.Where != nil {\n\t\treturn t.Where.Pos()\n\t}\n\treturn t.GroupBy.Pos()\n}\n\nfunc (t *TTLPolicy) End() Pos {\n\tif t.GroupBy != nil {\n\t\treturn t.GroupBy.End()\n\t}\n\tif t.Where != nil {\n\t\treturn t.Where.End()\n\t}\n\treturn t.Item.End()\n}\n\nfunc (t *TTLPolicy) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif t.Item != nil {\n\t\tif err := t.Item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif t.Where != nil {\n\t\tif err := t.Where.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif t.GroupBy != nil {\n\t\tif err := t.GroupBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTTLPolicy(t)\n}\n\ntype TTLExpr struct {\n\tTTLPos Pos\n\tExpr   Expr\n\tPolicy *TTLPolicy\n}\n\nfunc (t *TTLExpr) Pos() Pos {\n\treturn t.TTLPos\n}\n\nfunc (t *TTLExpr) End() Pos {\n\treturn t.Expr.End()\n}\n\nfunc (t *TTLExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif t.Policy != nil {\n\t\tif err := t.Policy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTTLExpr(t)\n}\n\ntype TTLClause struct {\n\tTTLPos  Pos\n\tListEnd Pos\n\tItems   []*TTLExpr\n}\n\nfunc (t *TTLClause) Pos() Pos {\n\treturn t.TTLPos\n}\n\nfunc (t *TTLClause) End() Pos {\n\treturn t.ListEnd\n}\n\nfunc (t *TTLClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tfor _, item := range t.Items {\n\t\tif err := item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTTLExprList(t)\n}\n\ntype Fill struct {\n\tFillPos   Pos\n\tFrom      Expr // optional\n\tTo        Expr // optional\n\tStep      Expr // optional\n\tStaleness Expr // optional\n}\n\nfunc (f *Fill) Pos() Pos {\n\treturn f.FillPos\n}\n\nfunc (f *Fill) End() Pos {\n\tif f.Staleness != nil {\n\t\treturn f.Staleness.End()\n\t}\n\tif f.Step != nil {\n\t\treturn f.Step.End()\n\t}\n\tif f.To != nil {\n\t\treturn f.To.End()\n\t}\n\tif f.From != nil {\n\t\treturn f.From.End()\n\t}\n\treturn f.FillPos + Pos(len(\"FILL\"))\n}\n\nfunc (f *Fill) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif f.From != nil {\n\t\tif err := f.From.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif f.To != nil {\n\t\tif err := f.To.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif f.Step != nil {\n\t\tif err := f.Step.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif f.Staleness != nil {\n\t\tif err := f.Staleness.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitFill(f)\n}\n\ntype OrderExpr struct {\n\tOrderPos  Pos\n\tExpr      Expr\n\tAlias     *Ident\n\tDirection OrderDirection\n\tFill      *Fill // optional WITH FILL clause\n}\n\nfunc (o *OrderExpr) Pos() Pos {\n\treturn o.OrderPos\n}\n\nfunc (o *OrderExpr) End() Pos {\n\tif o.Fill != nil {\n\t\treturn o.Fill.End()\n\t}\n\tif o.Alias != nil {\n\t\treturn o.Alias.End()\n\t}\n\treturn o.Expr.End()\n}\n\nfunc (o *OrderExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\tif err := o.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif o.Alias != nil {\n\t\tif err := o.Alias.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif o.Fill != nil {\n\t\tif err := o.Fill.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitOrderByExpr(o)\n}\n\ntype InterpolateItem struct {\n\tColumn *Ident\n\tExpr   Expr // optional AS expression\n}\n\nfunc (i *InterpolateItem) Pos() Pos {\n\treturn i.Column.Pos()\n}\n\nfunc (i *InterpolateItem) End() Pos {\n\tif i.Expr != nil {\n\t\treturn i.Expr.End()\n\t}\n\treturn i.Column.End()\n}\n\nfunc (i *InterpolateItem) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\tif err := i.Column.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif i.Expr != nil {\n\t\tif err := i.Expr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitInterpolateItem(i)\n}\n\ntype InterpolateClause struct {\n\tInterpolatePos Pos\n\tListEnd        Pos\n\tItems          []*InterpolateItem // can be nil for INTERPOLATE without columns\n}\n\nfunc (i *InterpolateClause) Pos() Pos {\n\treturn i.InterpolatePos\n}\n\nfunc (i *InterpolateClause) End() Pos {\n\treturn i.ListEnd\n}\n\nfunc (i *InterpolateClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\tfor _, item := range i.Items {\n\t\tif err := item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitInterpolateClause(i)\n}\n\ntype OrderByClause struct {\n\tOrderPos    Pos\n\tListEnd     Pos\n\tItems       []Expr\n\tInterpolate *InterpolateClause // optional INTERPOLATE clause\n}\n\nfunc (o *OrderByClause) Pos() Pos {\n\treturn o.OrderPos\n}\n\nfunc (o *OrderByClause) End() Pos {\n\tif o.Interpolate != nil {\n\t\treturn o.Interpolate.End()\n\t}\n\treturn o.ListEnd\n}\n\nfunc (o *OrderByClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\tfor _, item := range o.Items {\n\t\tif err := item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif o.Interpolate != nil {\n\t\tif err := o.Interpolate.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitOrderByListExpr(o)\n}\n\ntype SettingExpr struct {\n\tSettingsPos Pos\n\tName        *Ident\n\tExpr        Expr\n}\n\nfunc (s *SettingExpr) Pos() Pos {\n\treturn s.SettingsPos\n}\n\nfunc (s *SettingExpr) End() Pos {\n\treturn s.Expr.End()\n}\n\nfunc (s *SettingExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := s.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitSettingsExpr(s)\n}\n\ntype SettingsClause struct {\n\tSettingsPos Pos\n\tListEnd     Pos\n\tItems       []*SettingExpr\n}\n\nfunc (s *SettingsClause) Pos() Pos {\n\treturn s.SettingsPos\n}\n\nfunc (s *SettingsClause) End() Pos {\n\treturn s.ListEnd\n}\n\nfunc (s *SettingsClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tfor _, item := range s.Items {\n\t\tif err := item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSettingsExprList(s)\n}\n\ntype ParamExprList struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tItems         *ColumnExprList\n\tColumnArgList *ColumnArgList\n}\n\nfunc (f *ParamExprList) Pos() Pos {\n\treturn f.LeftParenPos\n}\n\nfunc (f *ParamExprList) End() Pos {\n\treturn f.RightParenPos\n}\n\nfunc (f *ParamExprList) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Items.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif f.ColumnArgList != nil {\n\t\tif err := f.ColumnArgList.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitParamExprList(f)\n}\n\ntype KeyValue struct {\n\tKey   StringLiteral\n\tValue Expr\n}\n\ntype MapLiteral struct {\n\tLBracePos Pos\n\tRBracePos Pos\n\tKeyValues []KeyValue\n}\n\nfunc (m *MapLiteral) Pos() Pos {\n\treturn m.LBracePos\n}\n\nfunc (m *MapLiteral) End() Pos {\n\treturn m.RBracePos\n}\n\nfunc (m *MapLiteral) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(m)\n\tdefer visitor.Leave(m)\n\tfor _, kv := range m.KeyValues {\n\t\tif err := kv.Key.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := kv.Value.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitMapLiteral(m)\n}\n\ntype NamedParameterExpr struct {\n\tNamePos Pos\n\tName    *Ident\n\tValue   Expr\n}\n\nfunc (n *NamedParameterExpr) Pos() Pos {\n\treturn n.NamePos\n}\n\nfunc (n *NamedParameterExpr) End() Pos {\n\treturn n.Value.End()\n}\n\nfunc (n *NamedParameterExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := n.Value.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitNamedParameterExpr(n)\n}\n\ntype QueryParam struct {\n\tLBracePos Pos\n\tRBracePos Pos\n\tName      *Ident\n\tType      ColumnType\n}\n\nfunc (q *QueryParam) Pos() Pos {\n\treturn q.LBracePos\n}\n\nfunc (q *QueryParam) End() Pos {\n\treturn q.RBracePos\n}\n\nfunc (q *QueryParam) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(q)\n\tdefer visitor.Leave(q)\n\tif err := q.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := q.Type.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitQueryParam(q)\n}\n\ntype ArrayParamList struct {\n\tLeftBracketPos  Pos\n\tRightBracketPos Pos\n\tItems           *ColumnExprList\n}\n\nfunc (a *ArrayParamList) Pos() Pos {\n\treturn a.LeftBracketPos\n}\n\nfunc (a *ArrayParamList) End() Pos {\n\treturn a.RightBracketPos\n}\n\nfunc (a *ArrayParamList) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Items.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitArrayParamList(a)\n}\n\ntype ObjectParams struct {\n\tObject Expr\n\tParams *ArrayParamList\n}\n\nfunc (o *ObjectParams) Pos() Pos {\n\treturn o.Object.Pos()\n}\n\nfunc (o *ObjectParams) End() Pos {\n\treturn o.Params.End()\n}\n\nfunc (o *ObjectParams) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\tif err := o.Object.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := o.Params.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitObjectParams(o)\n}\n\ntype FunctionExpr struct {\n\tName   *Ident\n\tParams *ParamExprList\n}\n\nfunc (f *FunctionExpr) Pos() Pos {\n\treturn f.Name.NamePos\n}\n\nfunc (f *FunctionExpr) End() Pos {\n\treturn f.Params.RightParenPos\n}\n\nfunc (f *FunctionExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := f.Params.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitFunctionExpr(f)\n}\n\ntype WindowFunctionExpr struct {\n\tFunction *FunctionExpr\n\tOverPos  Pos\n\tOverExpr Expr\n}\n\nfunc (w *WindowFunctionExpr) Pos() Pos {\n\treturn w.Function.Pos()\n}\n\nfunc (w *WindowFunctionExpr) End() Pos {\n\treturn w.OverExpr.End()\n}\n\nfunc (w *WindowFunctionExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tif err := w.Function.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := w.OverExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWindowFunctionExpr(w)\n}\n\ntype TypedPlaceholder struct {\n\tLeftBracePos  Pos\n\tRightBracePos Pos\n\tName          *Ident\n\tType          ColumnType\n}\n\nfunc (t *TypedPlaceholder) Pos() Pos {\n\treturn t.LeftBracePos\n}\n\nfunc (t *TypedPlaceholder) End() Pos {\n\treturn t.RightBracePos\n}\n\nfunc (t *TypedPlaceholder) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := t.Type.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTypedPlaceholder(t)\n}\n\ntype ColumnExpr struct {\n\tExpr  Expr\n\tAlias *Ident\n}\n\nfunc (c *ColumnExpr) Pos() Pos {\n\treturn c.Expr.Pos()\n}\n\nfunc (c *ColumnExpr) End() Pos {\n\tif c.Alias != nil {\n\t\treturn c.Alias.NameEnd\n\t}\n\treturn c.Expr.End()\n}\n\nfunc (c *ColumnExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.Alias != nil {\n\t\tif err := c.Alias.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitColumnExpr(c)\n}\n\ntype ColumnDef struct {\n\tNamePos   Pos\n\tColumnEnd Pos\n\tName      *NestedIdentifier\n\tType      ColumnType\n\tNotNull   *NotNullLiteral\n\tNullable  *NullLiteral\n\n\tDefaultExpr      Expr\n\tMaterializedExpr Expr\n\tAliasExpr        Expr\n\n\tCodec *CompressionCodec\n\tTTL   *TTLClause\n\n\tComment          *StringLiteral\n\tCompressionCodec *Ident\n}\n\nfunc (c *ColumnDef) Pos() Pos {\n\treturn c.Name.Pos()\n}\n\nfunc (c *ColumnDef) End() Pos {\n\treturn c.ColumnEnd\n}\n\nfunc (c *ColumnDef) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.Type != nil {\n\t\tif err := c.Type.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.NotNull != nil {\n\t\tif err := c.NotNull.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Nullable != nil {\n\t\tif err := c.Nullable.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.DefaultExpr != nil {\n\t\tif err := c.DefaultExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.MaterializedExpr != nil {\n\t\tif err := c.MaterializedExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.AliasExpr != nil {\n\t\tif err := c.AliasExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Codec != nil {\n\t\tif err := c.Codec.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.TTL != nil {\n\t\tif err := c.TTL.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Comment != nil {\n\t\tif err := c.Comment.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitColumnDef(c)\n}\n\ntype ColumnType interface {\n\tExpr\n\tType() string\n}\n\ntype ScalarType struct {\n\tName *Ident\n}\n\nfunc (s *ScalarType) Pos() Pos {\n\treturn s.Name.NamePos\n}\n\nfunc (s *ScalarType) End() Pos {\n\treturn s.Name.NameEnd\n}\n\nfunc (s *ScalarType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitScalarType(s)\n}\n\nfunc (s *ScalarType) Type() string {\n\treturn s.Name.Name\n}\n\ntype JSONPath struct {\n\tIdents []*Ident\n}\n\ntype JSONTypeHint struct {\n\tPath *JSONPath\n\tType ColumnType\n}\n\ntype JSONOption struct {\n\tSkipPath        *JSONPath\n\tSkipRegex       *StringLiteral\n\tMaxDynamicPaths *NumberLiteral\n\tMaxDynamicTypes *NumberLiteral\n\t// Type hint for specific JSON subcolumn path, e.g., \"message String\" or \"a.b UInt64\"\n\tColumn *JSONTypeHint\n}\n\ntype JSONOptions struct {\n\tLParen Pos\n\tRParen Pos\n\tItems  []*JSONOption\n}\n\nfunc (j *JSONOptions) Pos() Pos {\n\treturn j.LParen\n}\n\nfunc (j *JSONOptions) End() Pos {\n\treturn j.RParen\n}\n\ntype JSONType struct {\n\tName    *Ident\n\tOptions *JSONOptions\n}\n\nfunc (j *JSONType) Pos() Pos {\n\treturn j.Name.NamePos\n}\n\nfunc (j *JSONType) End() Pos {\n\tif j.Options != nil {\n\t\treturn j.Options.RParen\n\t}\n\treturn j.Name.NameEnd\n}\n\nfunc (j *JSONType) Type() string {\n\treturn j.Name.Name\n}\n\nfunc (j *JSONType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(j)\n\tdefer visitor.Leave(j)\n\tif err := j.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitJSONType(j)\n}\n\ntype PropertyType struct {\n\tName *Ident\n}\n\nfunc (c *PropertyType) Pos() Pos {\n\treturn c.Name.NamePos\n}\n\nfunc (c *PropertyType) End() Pos {\n\treturn c.Name.NameEnd\n}\n\nfunc (c *PropertyType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitPropertyType(c)\n}\n\nfunc (c *PropertyType) Type() string {\n\treturn c.Name.Name\n}\n\ntype TypeWithParams struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tName          *Ident\n\tParams        []Literal\n}\n\nfunc (s *TypeWithParams) Pos() Pos {\n\treturn s.Name.NamePos\n}\n\nfunc (s *TypeWithParams) End() Pos {\n\treturn s.RightParenPos\n}\n\nfunc (s *TypeWithParams) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, param := range s.Params {\n\t\tif err := param.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTypeWithParams(s)\n}\n\nfunc (s *TypeWithParams) Type() string {\n\treturn s.Name.Name\n}\n\ntype ComplexType struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tName          *Ident\n\tParams        []ColumnType\n}\n\nfunc (c *ComplexType) Pos() Pos {\n\treturn c.Name.NamePos\n}\n\nfunc (c *ComplexType) End() Pos {\n\treturn c.RightParenPos\n}\n\nfunc (c *ComplexType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, param := range c.Params {\n\t\tif err := param.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitComplexType(c)\n}\n\nfunc (c *ComplexType) Type() string {\n\treturn c.Name.Name\n}\n\ntype NestedType struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tName          *Ident\n\tColumns       []Expr\n}\n\nfunc (n *NestedType) Pos() Pos {\n\treturn n.Name.NamePos\n}\n\nfunc (n *NestedType) End() Pos {\n\treturn n.RightParenPos\n}\n\nfunc (n *NestedType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, column := range n.Columns {\n\t\tif err := column.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitNestedType(n)\n}\n\nfunc (n *NestedType) Type() string {\n\treturn n.Name.Name\n}\n\ntype CompressionCodec struct {\n\tCodecPos      Pos\n\tRightParenPos Pos\n\tType          *Ident\n\tTypeLevel     *NumberLiteral\n\tName          *Ident\n\tLevel         *NumberLiteral // compression level\n}\n\nfunc (c *CompressionCodec) Pos() Pos {\n\treturn c.CodecPos\n}\n\nfunc (c *CompressionCodec) End() Pos {\n\treturn c.RightParenPos\n}\n\nfunc (c *CompressionCodec) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif c.Type != nil {\n\t\tif err := c.Type.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.TypeLevel != nil {\n\t\tif err := c.TypeLevel.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Name != nil {\n\t\tif err := c.Name.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Level != nil {\n\t\tif err := c.Level.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCompressionCodec(c)\n}\n\ntype Literal interface {\n\tExpr\n}\n\ntype NumberLiteral struct {\n\tNumPos  Pos\n\tNumEnd  Pos\n\tLiteral string\n\tBase    int\n}\n\nfunc (n *NumberLiteral) Pos() Pos {\n\treturn n.NumPos\n}\n\nfunc (n *NumberLiteral) End() Pos {\n\treturn n.NumEnd\n}\n\nfunc (n *NumberLiteral) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\treturn visitor.VisitNumberLiteral(n)\n}\n\ntype StringLiteral struct {\n\tLiteralPos Pos\n\tLiteralEnd Pos\n\tLiteral    string\n}\n\nfunc (s *StringLiteral) Pos() Pos {\n\treturn s.LiteralPos\n}\n\nfunc (s *StringLiteral) End() Pos {\n\treturn s.LiteralEnd\n}\n\nfunc (s *StringLiteral) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\treturn visitor.VisitStringLiteral(s)\n}\n\ntype BoolLiteral struct {\n\tLiteralPos Pos\n\tLiteralEnd Pos\n\tLiteral    string\n}\n\nfunc (b *BoolLiteral) Pos() Pos {\n\treturn b.LiteralPos\n}\n\nfunc (b *BoolLiteral) End() Pos {\n\treturn b.LiteralEnd\n}\n\nfunc (b *BoolLiteral) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(b)\n\tdefer visitor.Leave(b)\n\treturn visitor.VisitBoolLiteral(b)\n}\n\ntype PlaceHolder struct {\n\tPlaceholderPos Pos\n\tPlaceHolderEnd Pos\n\tType           string\n}\n\nfunc (p *PlaceHolder) Pos() Pos {\n\treturn p.PlaceholderPos\n}\n\nfunc (p *PlaceHolder) End() Pos {\n\treturn p.PlaceHolderEnd\n}\n\nfunc (p *PlaceHolder) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\treturn visitor.VisitPlaceHolderExpr(p)\n}\n\ntype RatioExpr struct {\n\tNumerator *NumberLiteral\n\t// numberLiteral (SLASH numberLiteral)?\n\tDenominator *NumberLiteral\n}\n\nfunc (r *RatioExpr) Pos() Pos {\n\treturn r.Numerator.NumPos\n}\n\nfunc (r *RatioExpr) End() Pos {\n\tif r.Denominator != nil {\n\t\treturn r.Denominator.NumEnd\n\t}\n\treturn r.Numerator.NumEnd\n}\n\nfunc (r *RatioExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(r)\n\tdefer visitor.Leave(r)\n\tif err := r.Numerator.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif r.Denominator != nil {\n\t\tif err := r.Denominator.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitRatioExpr(r)\n}\n\ntype EnumValue struct {\n\tName  *StringLiteral\n\tValue *NumberLiteral\n}\n\nfunc (e *EnumValue) Pos() Pos {\n\treturn e.Name.Pos()\n}\n\nfunc (e *EnumValue) End() Pos {\n\treturn e.Value.End()\n}\n\nfunc (e *EnumValue) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(e)\n\tdefer visitor.Leave(e)\n\tif err := e.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := e.Value.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitEnumValue(e)\n}\n\ntype EnumType struct {\n\tName    *Ident\n\tListPos Pos\n\tListEnd Pos\n\tValues  []EnumValue\n}\n\nfunc (e *EnumType) Pos() Pos {\n\treturn e.ListPos\n}\n\nfunc (e *EnumType) End() Pos {\n\treturn e.ListEnd\n}\n\nfunc (e *EnumType) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(e)\n\tdefer visitor.Leave(e)\n\tif err := e.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor i := range e.Values {\n\t\tif err := e.Values[i].Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitEnumType(e)\n}\n\nfunc (e *EnumType) Type() string {\n\treturn e.Name.Name\n}\n\ntype IntervalExpr struct {\n\t// INTERVAL keyword position which might be omitted(IntervalPos = 0)\n\tIntervalPos Pos\n\n\tExpr Expr\n\tUnit *Ident\n}\n\nfunc (i *IntervalExpr) Pos() Pos {\n\tif i.IntervalPos != 0 {\n\t\treturn i.IntervalPos\n\t}\n\treturn i.Expr.Pos()\n}\n\nfunc (i *IntervalExpr) End() Pos {\n\treturn i.Unit.End()\n}\n\nfunc (i *IntervalExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\tif err := i.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := i.Unit.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitIntervalExpr(i)\n}\n\n// TODO(@git-hulk): split into EngineClause and EngineExpr\ntype EngineExpr struct {\n\tEnginePos   Pos\n\tEngineEnd   Pos\n\tName        string\n\tParams      *ParamExprList\n\tPrimaryKey  *PrimaryKeyClause\n\tPartitionBy *PartitionByClause\n\tSampleBy    *SampleByClause\n\tTTL         *TTLClause\n\tSettings    *SettingsClause\n\tOrderBy     *OrderByClause\n}\n\nfunc (e *EngineExpr) Pos() Pos {\n\treturn e.EnginePos\n}\n\nfunc (e *EngineExpr) End() Pos {\n\treturn e.EngineEnd\n}\n\nfunc (e *EngineExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(e)\n\tdefer visitor.Leave(e)\n\tif e.Params != nil {\n\t\tif err := e.Params.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e.PrimaryKey != nil {\n\t\tif err := e.PrimaryKey.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e.PartitionBy != nil {\n\t\tif err := e.PartitionBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e.SampleBy != nil {\n\t\tif err := e.SampleBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e.TTL != nil {\n\t\tif err := e.TTL.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e.Settings != nil {\n\t\tif err := e.Settings.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e.OrderBy != nil {\n\t\tif err := e.OrderBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitEngineExpr(e)\n}\n\ntype ColumnTypeExpr struct {\n\tName *Ident\n}\n\nfunc (c *ColumnTypeExpr) Pos() Pos {\n\treturn c.Name.NamePos\n}\n\nfunc (c *ColumnTypeExpr) End() Pos {\n\treturn c.Name.NameEnd\n}\n\nfunc (c *ColumnTypeExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitColumnTypeExpr(c)\n}\n\ntype ColumnArgList struct {\n\tDistinct      bool\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tItems         []Expr\n}\n\nfunc (c *ColumnArgList) Pos() Pos {\n\treturn c.LeftParenPos\n}\n\nfunc (c *ColumnArgList) End() Pos {\n\treturn c.RightParenPos\n}\n\nfunc (c *ColumnArgList) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tfor _, item := range c.Items {\n\t\tif err := item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitColumnArgList(c)\n}\n\ntype ColumnExprList struct {\n\tListPos     Pos\n\tListEnd     Pos\n\tHasDistinct bool\n\tItems       []Expr\n}\n\nfunc (c *ColumnExprList) Pos() Pos {\n\treturn c.ListPos\n}\n\nfunc (c *ColumnExprList) End() Pos {\n\treturn c.ListEnd\n}\n\nfunc (c *ColumnExprList) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tfor _, item := range c.Items {\n\t\tif err := item.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitColumnExprList(c)\n}\n\ntype WhenClause struct {\n\tWhenPos Pos\n\tThenPos Pos\n\tWhen    Expr\n\tThen    Expr\n\tElsePos Pos\n\tElse    Expr\n}\n\nfunc (w *WhenClause) Pos() Pos {\n\treturn w.WhenPos\n}\n\nfunc (w *WhenClause) End() Pos {\n\tif w.Else != nil {\n\t\treturn w.Else.End()\n\t}\n\treturn w.Then.End()\n}\n\nfunc (w *WhenClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tif err := w.When.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := w.Then.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif w.Else != nil {\n\t\tif err := w.Else.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitWhenExpr(w)\n}\n\ntype CaseExpr struct {\n\tCasePos Pos\n\tEndPos  Pos\n\tExpr    Expr // optional\n\tWhens   []*WhenClause\n\tElsePos Pos\n\tElse    Expr\n}\n\nfunc (c *CaseExpr) Pos() Pos {\n\treturn c.CasePos\n}\n\nfunc (c *CaseExpr) End() Pos {\n\treturn c.EndPos\n}\n\nfunc (c *CaseExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif c.Expr != nil {\n\t\tif err := c.Expr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, when := range c.Whens {\n\t\tif err := when.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Else != nil {\n\t\tif err := c.Else.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCaseExpr(c)\n}\n\ntype CastExpr struct {\n\tCastPos   Pos\n\tExpr      Expr\n\tSeparator string\n\tAsPos     Pos\n\tAsType    Expr\n}\n\nfunc (c *CastExpr) Pos() Pos {\n\treturn c.CastPos\n}\n\nfunc (c *CastExpr) End() Pos {\n\treturn c.AsType.End()\n}\n\nfunc (c *CastExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := c.AsType.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitCastExpr(c)\n}\n\ntype WithClause struct {\n\tWithPos Pos\n\tEndPos  Pos\n\tCTEs    []*CTEStmt\n}\n\nfunc (w *WithClause) Pos() Pos {\n\treturn w.WithPos\n}\n\nfunc (w *WithClause) End() Pos {\n\treturn w.EndPos\n}\n\nfunc (w *WithClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tfor _, cte := range w.CTEs {\n\t\tif err := cte.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitWithExpr(w)\n}\n\ntype TopClause struct {\n\tTopPos   Pos\n\tTopEnd   Pos\n\tNumber   *NumberLiteral\n\tWithTies bool\n}\n\nfunc (t *TopClause) Pos() Pos {\n\treturn t.TopPos\n}\n\nfunc (t *TopClause) End() Pos {\n\treturn t.TopEnd\n}\n\nfunc (t *TopClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Number.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTopExpr(t)\n}\n\ntype CreateLiveView struct {\n\tCreatePos    Pos\n\tStatementEnd Pos\n\tName         *TableIdentifier\n\tIfNotExists  bool\n\tUUID         *UUID\n\tOnCluster    *ClusterClause\n\tDestination  *DestinationClause\n\tTableSchema  *TableSchemaClause\n\tWithTimeout  *WithTimeoutClause\n\tSubQuery     *SubQuery\n}\n\nfunc (c *CreateLiveView) Type() string {\n\treturn \"LIVE_VIEW\"\n}\n\nfunc (c *CreateLiveView) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateLiveView) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateLiveView) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.UUID != nil {\n\t\tif err := c.UUID.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Destination != nil {\n\t\tif err := c.Destination.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.TableSchema != nil {\n\t\tif err := c.TableSchema.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.WithTimeout != nil {\n\t\tif err := c.WithTimeout.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.SubQuery != nil {\n\t\tif err := c.SubQuery.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateLiveView(c)\n}\n\ntype CreateDictionary struct {\n\tCreatePos    Pos\n\tStatementEnd Pos\n\tOrReplace    bool\n\tName         *TableIdentifier\n\tIfNotExists  bool\n\tUUID         *UUID\n\tOnCluster    *ClusterClause\n\tSchema       *DictionarySchemaClause\n\tEngine       *DictionaryEngineClause\n\tComment      *StringLiteral\n}\n\nfunc (c *CreateDictionary) Type() string {\n\treturn \"DICTIONARY\"\n}\n\nfunc (c *CreateDictionary) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateDictionary) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateDictionary) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.UUID != nil {\n\t\tif err := c.UUID.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Schema != nil {\n\t\tif err := c.Schema.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Engine != nil {\n\t\tif err := c.Engine.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif c.Comment != nil {\n\t\tif err := c.Comment.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateDictionary(c)\n}\n\ntype CreateNamedCollection struct {\n\tCreatePos    Pos\n\tStatementEnd Pos\n\tName         *Ident\n\tIfNotExists  bool\n\tOnCluster    *ClusterClause\n\tParams       []*NamedCollectionParam\n}\n\nfunc (c *CreateNamedCollection) Pos() Pos {\n\treturn c.CreatePos\n}\n\nfunc (c *CreateNamedCollection) End() Pos {\n\treturn c.StatementEnd\n}\n\nfunc (c *CreateNamedCollection) Type() string {\n\treturn \"NAMED COLLECTION\"\n}\n\nfunc (c *CreateNamedCollection) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.OnCluster != nil {\n\t\tif err := c.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, param := range c.Params {\n\t\tif err := param.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCreateNamedCollection(c)\n}\n\ntype NamedCollectionParam struct {\n\tParamPos       Pos\n\tName           *Ident\n\tValue          Expr\n\tOverridable    bool\n\tNotOverridable bool\n}\n\nfunc (n *NamedCollectionParam) Pos() Pos {\n\treturn n.ParamPos\n}\n\nfunc (n *NamedCollectionParam) End() Pos {\n\treturn n.Value.End()\n}\n\nfunc (n *NamedCollectionParam) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := n.Value.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitNamedCollectionParam(n)\n}\n\ntype DictionarySchemaClause struct {\n\tSchemaPos  Pos\n\tAttributes []*DictionaryAttribute\n\tRParenPos  Pos\n}\n\nfunc (d *DictionarySchemaClause) Pos() Pos {\n\treturn d.SchemaPos\n}\n\nfunc (d *DictionarySchemaClause) End() Pos {\n\treturn d.RParenPos + 1\n}\n\nfunc (d *DictionarySchemaClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tfor _, attr := range d.Attributes {\n\t\tif err := attr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDictionarySchemaClause(d)\n}\n\ntype DictionaryAttribute struct {\n\tNamePos      Pos\n\tName         *Ident\n\tType         ColumnType\n\tDefault      Literal\n\tExpression   Expr\n\tHierarchical bool\n\tInjective    bool\n\tIsObjectId   bool\n}\n\nfunc (d *DictionaryAttribute) Pos() Pos {\n\treturn d.NamePos\n}\n\nfunc (d *DictionaryAttribute) End() Pos {\n\tif d.IsObjectId {\n\t\treturn d.NamePos + Pos(len(\"IS_OBJECT_ID\"))\n\t}\n\tif d.Injective {\n\t\treturn d.NamePos + Pos(len(\"INJECTIVE\"))\n\t}\n\tif d.Hierarchical {\n\t\treturn d.NamePos + Pos(len(\"HIERARCHICAL\"))\n\t}\n\tif d.Expression != nil {\n\t\treturn d.Expression.End()\n\t}\n\tif d.Default != nil {\n\t\treturn d.Default.End()\n\t}\n\treturn d.Type.End()\n}\n\nfunc (d *DictionaryAttribute) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := d.Type.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif d.Default != nil {\n\t\tif err := d.Default.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Expression != nil {\n\t\tif err := d.Expression.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDictionaryAttribute(d)\n}\n\ntype DictionaryEngineClause struct {\n\tEnginePos  Pos\n\tPrimaryKey *DictionaryPrimaryKeyClause\n\tSource     *DictionarySourceClause\n\tLifetime   *DictionaryLifetimeClause\n\tLayout     *DictionaryLayoutClause\n\tRange      *DictionaryRangeClause\n\tSettings   *SettingsClause\n}\n\nfunc (d *DictionaryEngineClause) Pos() Pos {\n\treturn d.EnginePos\n}\n\nfunc (d *DictionaryEngineClause) End() Pos {\n\tif d.Settings != nil {\n\t\treturn d.Settings.End()\n\t}\n\tif d.Range != nil {\n\t\treturn d.Range.End()\n\t}\n\tif d.Layout != nil {\n\t\treturn d.Layout.End()\n\t}\n\tif d.Lifetime != nil {\n\t\treturn d.Lifetime.End()\n\t}\n\tif d.Source != nil {\n\t\treturn d.Source.End()\n\t}\n\tif d.PrimaryKey != nil {\n\t\treturn d.PrimaryKey.End()\n\t}\n\treturn d.EnginePos\n}\n\nfunc (d *DictionaryEngineClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif d.PrimaryKey != nil {\n\t\tif err := d.PrimaryKey.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Source != nil {\n\t\tif err := d.Source.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Lifetime != nil {\n\t\tif err := d.Lifetime.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Layout != nil {\n\t\tif err := d.Layout.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Range != nil {\n\t\tif err := d.Range.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Settings != nil {\n\t\tif err := d.Settings.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDictionaryEngineClause(d)\n}\n\ntype DictionaryPrimaryKeyClause struct {\n\tPrimaryKeyPos Pos\n\tKeys          *ColumnExprList\n\tRParenPos     Pos\n}\n\nfunc (d *DictionaryPrimaryKeyClause) Pos() Pos {\n\treturn d.PrimaryKeyPos\n}\n\nfunc (d *DictionaryPrimaryKeyClause) End() Pos {\n\treturn d.RParenPos + 1\n}\n\nfunc (d *DictionaryPrimaryKeyClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Keys.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitDictionaryPrimaryKeyClause(d)\n}\n\ntype DictionarySourceClause struct {\n\tSourcePos Pos\n\tSource    *Ident\n\tArgs      []*DictionaryArgExpr\n\tRParenPos Pos\n}\n\nfunc (d *DictionarySourceClause) Pos() Pos {\n\treturn d.SourcePos\n}\n\nfunc (d *DictionarySourceClause) End() Pos {\n\treturn d.RParenPos + 1\n}\n\nfunc (d *DictionarySourceClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Source.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, arg := range d.Args {\n\t\tif err := arg.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDictionarySourceClause(d)\n}\n\ntype DictionaryArgExpr struct {\n\tArgPos Pos\n\tName   *Ident\n\tValue  Expr // can be Ident with optional parentheses or literal\n}\n\nfunc (d *DictionaryArgExpr) Pos() Pos {\n\treturn d.ArgPos\n}\n\nfunc (d *DictionaryArgExpr) End() Pos {\n\treturn d.Value.End()\n}\n\nfunc (d *DictionaryArgExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := d.Value.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitDictionaryArgExpr(d)\n}\n\ntype DictionaryLifetimeClause struct {\n\tLifetimePos Pos\n\tMin         *NumberLiteral\n\tMax         *NumberLiteral\n\tValue       *NumberLiteral // for simple LIFETIME(value) form\n\tRParenPos   Pos\n}\n\nfunc (d *DictionaryLifetimeClause) Pos() Pos {\n\treturn d.LifetimePos\n}\n\nfunc (d *DictionaryLifetimeClause) End() Pos {\n\treturn d.RParenPos + 1\n}\n\nfunc (d *DictionaryLifetimeClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif d.Value != nil {\n\t\tif err := d.Value.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Min != nil {\n\t\tif err := d.Min.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Max != nil {\n\t\tif err := d.Max.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDictionaryLifetimeClause(d)\n}\n\ntype DictionaryLayoutClause struct {\n\tLayoutPos Pos\n\tLayout    *Ident\n\tArgs      []*DictionaryArgExpr\n\tRParenPos Pos\n}\n\nfunc (d *DictionaryLayoutClause) Pos() Pos {\n\treturn d.LayoutPos\n}\n\nfunc (d *DictionaryLayoutClause) End() Pos {\n\treturn d.RParenPos + 1\n}\n\nfunc (d *DictionaryLayoutClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Layout.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, arg := range d.Args {\n\t\tif err := arg.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDictionaryLayoutClause(d)\n}\n\ntype DictionaryRangeClause struct {\n\tRangePos  Pos\n\tMin       *Ident\n\tMax       *Ident\n\tRParenPos Pos\n}\n\nfunc (d *DictionaryRangeClause) Pos() Pos {\n\treturn d.RangePos\n}\n\nfunc (d *DictionaryRangeClause) End() Pos {\n\treturn d.RParenPos + 1\n}\n\nfunc (d *DictionaryRangeClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Min.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := d.Max.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitDictionaryRangeClause(d)\n}\n\ntype WithTimeoutClause struct {\n\tWithTimeoutPos Pos\n\tExpr           Expr\n\tNumber         *NumberLiteral\n}\n\nfunc (w *WithTimeoutClause) Pos() Pos {\n\treturn w.WithTimeoutPos\n}\n\nfunc (w *WithTimeoutClause) End() Pos {\n\treturn w.Number.End()\n}\n\nfunc (w *WithTimeoutClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tif err := w.Number.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWithTimeoutExpr(w)\n}\n\ntype TableExpr struct {\n\tTablePos Pos\n\tTableEnd Pos\n\tAlias    *AliasExpr\n\tExpr     Expr\n\tHasFinal bool\n}\n\nfunc (t *TableExpr) Pos() Pos {\n\treturn t.TablePos\n}\n\nfunc (t *TableExpr) End() Pos {\n\treturn t.TableEnd\n}\n\nfunc (t *TableExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif t.Alias != nil {\n\t\tif err := t.Alias.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTableExpr(t)\n}\n\ntype OnClause struct {\n\tOnPos Pos\n\tOn    *ColumnExprList\n}\n\nfunc (o *OnClause) Pos() Pos {\n\treturn o.OnPos\n}\n\nfunc (o *OnClause) End() Pos {\n\treturn o.On.End()\n}\n\nfunc (o *OnClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\tif err := o.On.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitOnExpr(o)\n}\n\ntype UsingClause struct {\n\tUsingPos Pos\n\tUsing    *ColumnExprList\n}\n\nfunc (u *UsingClause) Pos() Pos {\n\treturn u.UsingPos\n}\n\nfunc (u *UsingClause) End() Pos {\n\treturn u.Using.End()\n}\n\nfunc (u *UsingClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(u)\n\tdefer visitor.Leave(u)\n\tif err := u.Using.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitUsingExpr(u)\n}\n\ntype JoinExpr struct {\n\tJoinPos     Pos\n\tLeft        Expr\n\tRight       Expr\n\tModifiers   []string\n\tConstraints Expr\n}\n\nfunc (j *JoinExpr) Pos() Pos {\n\treturn j.JoinPos\n}\n\nfunc (j *JoinExpr) End() Pos {\n\t// Return the rightmost position\n\tif j.Right != nil {\n\t\treturn j.Right.End()\n\t}\n\tif j.Constraints != nil {\n\t\treturn j.Constraints.End()\n\t}\n\treturn j.Left.End()\n}\n\nfunc (j *JoinExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(j)\n\tdefer visitor.Leave(j)\n\tif err := j.Left.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif j.Right != nil {\n\t\tif err := j.Right.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif j.Constraints != nil {\n\t\tif err := j.Constraints.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitJoinExpr(j)\n}\n\ntype JoinConstraintClause struct {\n\tConstraintPos Pos\n\tOn            *ColumnExprList\n\tUsing         *ColumnExprList\n}\n\nfunc (j *JoinConstraintClause) Pos() Pos {\n\treturn j.ConstraintPos\n}\n\nfunc (j *JoinConstraintClause) End() Pos {\n\tif j.On != nil {\n\t\treturn j.On.End()\n\t}\n\treturn j.Using.End()\n}\n\nfunc (j *JoinConstraintClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(j)\n\tdefer visitor.Leave(j)\n\tif j.On != nil {\n\t\tif err := j.On.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif j.Using != nil {\n\t\tif err := j.Using.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitJoinConstraintExpr(j)\n}\n\ntype FromClause struct {\n\tFromPos Pos\n\tExpr    Expr\n}\n\nfunc (f *FromClause) Pos() Pos {\n\treturn f.FromPos\n}\n\nfunc (f *FromClause) End() Pos {\n\treturn f.Expr.End()\n}\n\nfunc (f *FromClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitFromExpr(f)\n}\n\ntype IsNullExpr struct {\n\tIsPos Pos\n\tExpr  Expr\n}\n\nfunc (n *IsNullExpr) Pos() Pos {\n\treturn n.IsPos\n}\n\nfunc (n *IsNullExpr) End() Pos {\n\treturn n.Expr.End()\n}\n\nfunc (n *IsNullExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitIsNullExpr(n)\n}\n\ntype IsNotNullExpr struct {\n\tIsPos Pos\n\tExpr  Expr\n}\n\nfunc (n *IsNotNullExpr) Pos() Pos {\n\treturn n.Expr.Pos()\n}\n\nfunc (n *IsNotNullExpr) End() Pos {\n\treturn n.Expr.End()\n}\n\nfunc (n *IsNotNullExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitIsNotNullExpr(n)\n}\n\ntype AliasExpr struct {\n\tExpr     Expr\n\tAliasPos Pos\n\tAlias    Expr\n}\n\nfunc (a *AliasExpr) Pos() Pos {\n\treturn a.AliasPos\n}\n\nfunc (a *AliasExpr) End() Pos {\n\treturn a.Alias.End()\n}\n\nfunc (a *AliasExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(a)\n\tdefer visitor.Leave(a)\n\tif err := a.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := a.Alias.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitAliasExpr(a)\n}\n\ntype WhereClause struct {\n\tWherePos Pos\n\tExpr     Expr\n}\n\nfunc (w *WhereClause) Pos() Pos {\n\treturn w.WherePos\n}\n\nfunc (w *WhereClause) End() Pos {\n\treturn w.Expr.End()\n}\n\nfunc (w *WhereClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tif err := w.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWhereExpr(w)\n}\n\ntype PrewhereClause struct {\n\tPrewherePos Pos\n\tExpr        Expr\n}\n\nfunc (w *PrewhereClause) Pos() Pos {\n\treturn w.PrewherePos\n}\n\nfunc (w *PrewhereClause) End() Pos {\n\treturn w.Expr.End()\n}\n\nfunc (w *PrewhereClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tif err := w.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitPrewhereExpr(w)\n}\n\ntype GroupByClause struct {\n\tGroupByPos    Pos\n\tGroupByEnd    Pos\n\tAggregateType string\n\tExpr          Expr\n\tWithCube      bool\n\tWithRollup    bool\n\tWithTotals    bool\n}\n\nfunc (g *GroupByClause) Pos() Pos {\n\treturn g.GroupByPos\n}\n\nfunc (g *GroupByClause) End() Pos {\n\treturn g.GroupByEnd\n}\n\nfunc (g *GroupByClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(g)\n\tdefer visitor.Leave(g)\n\tif g.Expr != nil {\n\t\tif err := g.Expr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitGroupByExpr(g)\n}\n\ntype HavingClause struct {\n\tHavingPos Pos\n\tExpr      Expr\n}\n\nfunc (h *HavingClause) Pos() Pos {\n\treturn h.HavingPos\n}\n\nfunc (h *HavingClause) End() Pos {\n\treturn h.Expr.End()\n}\n\nfunc (h *HavingClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(h)\n\tdefer visitor.Leave(h)\n\tif err := h.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitHavingExpr(h)\n}\n\ntype LimitClause struct {\n\tLimitPos Pos\n\tLimit    Expr\n\tOffset   Expr\n}\n\nfunc (l *LimitClause) Pos() Pos {\n\treturn l.LimitPos\n}\n\nfunc (l *LimitClause) End() Pos {\n\tif l.Offset != nil {\n\t\treturn l.Offset.End()\n\t}\n\treturn l.Limit.End()\n}\n\nfunc (l *LimitClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(l)\n\tdefer visitor.Leave(l)\n\tif l.Limit != nil {\n\t\tif err := l.Limit.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif l.Offset != nil {\n\t\tif err := l.Offset.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitLimitExpr(l)\n}\n\ntype LimitByClause struct {\n\tLimit  *LimitClause\n\tByExpr *ColumnExprList\n}\n\nfunc (l *LimitByClause) Pos() Pos {\n\treturn l.Limit.Pos()\n}\n\nfunc (l *LimitByClause) End() Pos {\n\tif l.ByExpr != nil {\n\t\treturn l.ByExpr.End()\n\t}\n\tif l.Limit != nil {\n\t\treturn l.Limit.End()\n\t}\n\treturn l.Limit.End()\n}\n\nfunc (l *LimitByClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(l)\n\tdefer visitor.Leave(l)\n\tif l.Limit != nil {\n\t\tif err := l.Limit.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif l.ByExpr != nil {\n\t\tif err := l.ByExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitLimitByExpr(l)\n}\n\ntype WindowExpr struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tWindowName    *Ident\n\tPartitionBy   *PartitionByClause\n\tOrderBy       *OrderByClause\n\tFrame         *WindowFrameClause\n}\n\nfunc (w *WindowExpr) Pos() Pos {\n\treturn w.LeftParenPos\n}\n\nfunc (w *WindowExpr) End() Pos {\n\treturn w.RightParenPos\n}\n\nfunc (w *WindowExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tif w.WindowName != nil {\n\t\tif err := w.WindowName.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif w.PartitionBy != nil {\n\t\tif err := w.PartitionBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif w.OrderBy != nil {\n\t\tif err := w.OrderBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif w.Frame != nil {\n\t\tif err := w.Frame.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitWindowConditionExpr(w)\n}\n\ntype WindowDefinition struct {\n\tName  *Ident\n\tAsPos Pos\n\tExpr  *WindowExpr\n}\n\nfunc (w *WindowDefinition) Pos() Pos {\n\tif w == nil || w.Name == nil {\n\t\treturn 0\n\t}\n\treturn w.Name.Pos()\n}\n\nfunc (w *WindowDefinition) End() Pos {\n\tif w == nil || w.Expr == nil {\n\t\treturn 0\n\t}\n\treturn w.Expr.End()\n}\n\ntype WindowClause struct {\n\tWindowPos Pos\n\tEndPos    Pos\n\tWindows   []*WindowDefinition\n}\n\nfunc (w *WindowClause) Pos() Pos {\n\treturn w.WindowPos\n}\n\nfunc (w *WindowClause) End() Pos {\n\tif w.EndPos != 0 {\n\t\treturn w.EndPos\n\t}\n\tif len(w.Windows) == 0 {\n\t\treturn w.WindowPos\n\t}\n\treturn w.Windows[len(w.Windows)-1].End()\n}\n\nfunc (w *WindowClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(w)\n\tdefer visitor.Leave(w)\n\tfor _, window := range w.Windows {\n\t\tif window == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif window.Name != nil {\n\t\t\tif err := window.Name.Accept(visitor); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif window.Expr != nil {\n\t\t\tif err := window.Expr.Accept(visitor); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn visitor.VisitWindowExpr(w)\n}\n\ntype WindowFrameClause struct {\n\tFramePos Pos\n\tType     string\n\tExtend   Expr\n}\n\nfunc (f *WindowFrameClause) Pos() Pos {\n\treturn f.FramePos\n}\n\nfunc (f *WindowFrameClause) End() Pos {\n\treturn f.Extend.End()\n}\n\nfunc (f *WindowFrameClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Extend.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWindowFrameExpr(f)\n}\n\ntype WindowFrameExtendExpr struct {\n\tExpr      Expr\n\tDirection string\n\tEndPos    Pos\n}\n\nfunc (f *WindowFrameExtendExpr) Pos() Pos {\n\treturn f.Expr.Pos()\n}\n\nfunc (f *WindowFrameExtendExpr) End() Pos {\n\tif f.EndPos != 0 {\n\t\treturn f.EndPos\n\t}\n\treturn f.Expr.End()\n}\n\nfunc (f *WindowFrameExtendExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWindowFrameExtendExpr(f)\n}\n\ntype BetweenClause struct {\n\tExpr    Expr\n\tBetween Expr\n\tAndPos  Pos\n\tAnd     Expr\n}\n\nfunc (f *BetweenClause) Pos() Pos {\n\tif f.Expr != nil {\n\t\treturn f.Expr.Pos()\n\t}\n\treturn f.Between.Pos()\n}\n\nfunc (f *BetweenClause) End() Pos {\n\treturn f.And.End()\n}\n\nfunc (f *BetweenClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif f.Expr != nil {\n\t\tif err := f.Expr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := f.Between.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := f.And.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitBetweenClause(f)\n}\n\ntype WindowFrameCurrentRow struct {\n\tCurrentPos Pos\n\tRowEnd     Pos\n}\n\nfunc (f *WindowFrameCurrentRow) Pos() Pos {\n\treturn f.CurrentPos\n}\n\nfunc (f *WindowFrameCurrentRow) End() Pos {\n\treturn f.RowEnd\n}\n\nfunc (f *WindowFrameCurrentRow) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\treturn visitor.VisitWindowFrameCurrentRow(f)\n}\n\ntype WindowFrameUnbounded struct {\n\tUnboundedPos Pos\n\tUnboundedEnd Pos\n\tDirection    string\n}\n\nfunc (f *WindowFrameUnbounded) Pos() Pos {\n\treturn f.UnboundedPos\n}\n\nfunc (f *WindowFrameUnbounded) End() Pos {\n\treturn f.UnboundedEnd\n}\n\nfunc (f *WindowFrameUnbounded) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\treturn visitor.VisitWindowFrameUnbounded(f)\n}\n\ntype WindowFrameNumber struct {\n\tNumber    *NumberLiteral\n\tEndPos    Pos\n\tDirection string\n}\n\nfunc (f *WindowFrameNumber) Pos() Pos {\n\treturn f.Number.Pos()\n}\n\nfunc (f *WindowFrameNumber) End() Pos {\n\treturn f.EndPos\n}\n\nfunc (f *WindowFrameNumber) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Number.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWindowFrameNumber(f)\n}\n\ntype WindowFrameParam struct {\n\tParam     *QueryParam\n\tEndPos    Pos\n\tDirection string\n}\n\nfunc (f *WindowFrameParam) Pos() Pos {\n\treturn f.Param.Pos()\n}\n\nfunc (f *WindowFrameParam) End() Pos {\n\treturn f.EndPos\n}\n\nfunc (f *WindowFrameParam) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Param.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitWindowFrameParam(f)\n}\n\ntype SelectQuery struct {\n\tSelectPos     Pos\n\tStatementEnd  Pos\n\tWith          *WithClause\n\tTop           *TopClause\n\tHasDistinct   bool\n\tDistinctOn    *DistinctOn\n\tSelectItems   []*SelectItem\n\tFrom          *FromClause\n\tWindow        *WindowClause\n\tPrewhere      *PrewhereClause\n\tWhere         *WhereClause\n\tGroupBy       *GroupByClause\n\tWithTotal     bool\n\tHaving        *HavingClause\n\tOrderBy       *OrderByClause\n\tLimitBy       *LimitByClause\n\tLimit         *LimitClause\n\tSettings      *SettingsClause\n\tFormat        *FormatClause\n\tUnionAll      *SelectQuery\n\tUnionDistinct *SelectQuery\n\tExcept        *SelectQuery\n}\n\nfunc (s *SelectQuery) Pos() Pos {\n\treturn s.SelectPos\n}\n\nfunc (s *SelectQuery) End() Pos {\n\treturn s.StatementEnd\n}\n\nfunc (s *SelectQuery) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif s.With != nil {\n\t\tif err := s.With.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Top != nil {\n\t\tif err := s.Top.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.SelectItems != nil {\n\t\tfor _, item := range s.SelectItems {\n\t\t\tif err := item.Accept(visitor); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tif s.From != nil {\n\t\tif err := s.From.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Window != nil {\n\t\tif err := s.Window.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Prewhere != nil {\n\t\tif err := s.Prewhere.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Where != nil {\n\t\tif err := s.Where.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.GroupBy != nil {\n\t\tif err := s.GroupBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Having != nil {\n\t\tif err := s.Having.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.OrderBy != nil {\n\t\tif err := s.OrderBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.LimitBy != nil {\n\t\tif err := s.LimitBy.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Limit != nil {\n\t\tif err := s.Limit.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Settings != nil {\n\t\tif err := s.Settings.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Format != nil {\n\t\tif err := s.Format.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.UnionAll != nil {\n\t\tif err := s.UnionAll.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.UnionDistinct != nil {\n\t\tif err := s.UnionDistinct.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Except != nil {\n\t\tif err := s.Except.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSelectQuery(s)\n}\n\ntype DistinctOn struct {\n\tIdents        []*NestedIdentifier\n\tDistinctOnPos Pos\n\tDistinctOnEnd Pos\n}\n\nfunc (s *DistinctOn) Pos() Pos {\n\treturn s.DistinctOnPos\n}\n\nfunc (s *DistinctOn) End() Pos {\n\treturn s.DistinctOnEnd\n}\n\nfunc (s *DistinctOn) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tfor _, ident := range s.Idents {\n\t\tif err := ident.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDistinctOn(s)\n}\n\ntype SubQuery struct {\n\tHasParen bool\n\tSelect   *SelectQuery\n}\n\nfunc (s *SubQuery) Pos() Pos {\n\treturn s.Select.Pos()\n}\n\nfunc (s *SubQuery) End() Pos {\n\treturn s.Select.End()\n}\n\nfunc (s *SubQuery) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif s.Select != nil {\n\t\tif err := s.Select.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSubQueryExpr(s)\n}\n\ntype NotExpr struct {\n\tNotPos Pos\n\tExpr   Expr\n}\n\nfunc (n *NotExpr) Pos() Pos {\n\treturn n.NotPos\n}\n\nfunc (n *NotExpr) End() Pos {\n\treturn n.Expr.End()\n}\n\nfunc (n *NotExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitNotExpr(n)\n}\n\ntype NegateExpr struct {\n\tNegatePos Pos\n\tExpr      Expr\n}\n\nfunc (n *NegateExpr) Pos() Pos {\n\treturn n.NegatePos\n}\n\nfunc (n *NegateExpr) End() Pos {\n\treturn n.Expr.End()\n}\n\nfunc (n *NegateExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitNegateExpr(n)\n}\n\ntype GlobalInOperation struct {\n\tGlobalPos Pos\n\tExpr      Expr\n}\n\nfunc (g *GlobalInOperation) Pos() Pos {\n\treturn g.GlobalPos\n}\n\nfunc (g *GlobalInOperation) End() Pos {\n\treturn g.Expr.End()\n}\n\nfunc (g *GlobalInOperation) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(g)\n\tdefer visitor.Leave(g)\n\tif err := g.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitGlobalInExpr(g)\n}\n\ntype IntervalFrom struct {\n\tInterval *Ident\n\tFromPos  Pos\n\tFromExpr Expr\n}\n\nfunc (i *IntervalFrom) Pos() Pos {\n\treturn i.Interval.NamePos\n}\n\nfunc (i *IntervalFrom) End() Pos {\n\treturn i.FromExpr.End()\n}\n\nfunc (i *IntervalFrom) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\tif err := i.FromExpr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitIntervalFrom(i)\n}\n\ntype ExtractExpr struct {\n\tExtractPos Pos\n\tExtractEnd Pos\n\tParameters []Expr\n}\n\nfunc (e *ExtractExpr) Pos() Pos {\n\treturn e.ExtractPos\n}\n\nfunc (e *ExtractExpr) End() Pos {\n\treturn e.ExtractEnd\n}\n\nfunc (e *ExtractExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(e)\n\tdefer visitor.Leave(e)\n\tfor _, param := range e.Parameters {\n\t\tif err := param.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitExtractExpr(e)\n}\n\ntype DropDatabase struct {\n\tDropPos      Pos\n\tStatementEnd Pos\n\tName         *Ident\n\tIfExists     bool\n\tOnCluster    *ClusterClause\n}\n\nfunc (d *DropDatabase) Pos() Pos {\n\treturn d.DropPos\n}\n\nfunc (d *DropDatabase) End() Pos {\n\treturn d.StatementEnd\n}\n\nfunc (d *DropDatabase) Type() string {\n\treturn \"DATABASE\"\n}\n\nfunc (d *DropDatabase) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif d.OnCluster != nil {\n\t\tif err := d.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDropDatabase(d)\n}\n\ntype DropStmt struct {\n\tDropPos      Pos\n\tStatementEnd Pos\n\n\tDropTarget  string\n\tName        *TableIdentifier\n\tIfExists    bool\n\tOnCluster   *ClusterClause\n\tIsTemporary bool\n\tModifier    string\n}\n\nfunc (d *DropStmt) Pos() Pos {\n\treturn d.DropPos\n}\n\nfunc (d *DropStmt) End() Pos {\n\treturn d.StatementEnd\n}\n\nfunc (d *DropStmt) Type() string {\n\treturn \"DROP \" + d.DropTarget\n}\n\nfunc (d *DropStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif d.OnCluster != nil {\n\t\tif err := d.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDropStmt(d)\n\n}\n\ntype DropUserOrRole struct {\n\tDropPos      Pos\n\tTarget       string\n\tStatementEnd Pos\n\tNames        []*RoleName\n\tIfExists     bool\n\tModifier     string\n\tFrom         *Ident\n}\n\nfunc (d *DropUserOrRole) Pos() Pos {\n\treturn d.DropPos\n}\n\nfunc (d *DropUserOrRole) End() Pos {\n\treturn d.StatementEnd\n}\n\nfunc (d *DropUserOrRole) Type() string {\n\treturn d.Target\n}\n\nfunc (d *DropUserOrRole) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tfor _, name := range d.Names {\n\t\tif err := name.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.From != nil {\n\t\tif err := d.From.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDropUserOrRole(d)\n}\n\ntype UseStmt struct {\n\tUsePos       Pos\n\tStatementEnd Pos\n\tDatabase     *Ident\n}\n\nfunc (u *UseStmt) Pos() Pos {\n\treturn u.UsePos\n}\n\nfunc (u *UseStmt) End() Pos {\n\treturn u.Database.End()\n}\n\nfunc (u *UseStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(u)\n\tdefer visitor.Leave(u)\n\tif err := u.Database.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitUseExpr(u)\n}\n\ntype CTEStmt struct {\n\tCTEPos Pos\n\tExpr   Expr\n\tAlias  Expr\n}\n\nfunc (c *CTEStmt) Pos() Pos {\n\treturn c.CTEPos\n}\n\nfunc (c *CTEStmt) End() Pos {\n\treturn c.Expr.End()\n}\n\nfunc (c *CTEStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := c.Alias.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitCTEExpr(c)\n}\n\ntype SetStmt struct {\n\tSetPos   Pos\n\tSettings *SettingsClause\n}\n\nfunc (s *SetStmt) Pos() Pos {\n\treturn s.SetPos\n}\n\nfunc (s *SetStmt) End() Pos {\n\treturn s.Settings.End()\n}\n\nfunc (s *SetStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Settings.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitSetExpr(s)\n}\n\ntype FormatClause struct {\n\tFormatPos Pos\n\tFormat    *Ident\n}\n\nfunc (f *FormatClause) Pos() Pos {\n\treturn f.FormatPos\n}\n\nfunc (f *FormatClause) End() Pos {\n\treturn f.Format.End()\n}\n\nfunc (f *FormatClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(f)\n\tdefer visitor.Leave(f)\n\tif err := f.Format.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitFormatExpr(f)\n}\n\ntype OptimizeStmt struct {\n\tOptimizePos  Pos\n\tStatementEnd Pos\n\tTable        *TableIdentifier\n\tOnCluster    *ClusterClause\n\tPartition    *PartitionClause\n\tHasFinal     bool\n\tDeduplicate  *DeduplicateClause\n}\n\nfunc (o *OptimizeStmt) Pos() Pos {\n\treturn o.OptimizePos\n}\n\nfunc (o *OptimizeStmt) End() Pos {\n\treturn o.StatementEnd\n}\n\nfunc (o *OptimizeStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(o)\n\tdefer visitor.Leave(o)\n\tif err := o.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif o.OnCluster != nil {\n\t\tif err := o.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif o.Partition != nil {\n\t\tif err := o.Partition.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif o.Deduplicate != nil {\n\t\tif err := o.Deduplicate.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitOptimizeExpr(o)\n}\n\ntype DeduplicateClause struct {\n\tDeduplicatePos Pos\n\tBy             *ColumnExprList\n\tExcept         *ColumnExprList\n}\n\nfunc (d *DeduplicateClause) Pos() Pos {\n\treturn d.DeduplicatePos\n}\n\nfunc (d *DeduplicateClause) End() Pos {\n\tif d.By != nil {\n\t\treturn d.By.End()\n\t} else if d.Except != nil {\n\t\treturn d.Except.End()\n\t}\n\treturn d.DeduplicatePos + Pos(len(KeywordDeduplicate))\n}\n\nfunc (d *DeduplicateClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif d.By != nil {\n\t\tif err := d.By.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.Except != nil {\n\t\tif err := d.Except.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDeduplicateExpr(d)\n}\n\ntype SystemStmt struct {\n\tSystemPos Pos\n\tExpr      Expr\n}\n\nfunc (s *SystemStmt) Pos() Pos {\n\treturn s.SystemPos\n}\n\nfunc (s *SystemStmt) End() Pos {\n\treturn s.Expr.End()\n}\n\nfunc (s *SystemStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitSystemExpr(s)\n}\n\ntype SystemFlushExpr struct {\n\tFlushPos     Pos\n\tStatementEnd Pos\n\tLogs         bool\n\tDistributed  *TableIdentifier\n}\n\nfunc (s *SystemFlushExpr) Pos() Pos {\n\treturn s.FlushPos\n}\n\nfunc (s *SystemFlushExpr) End() Pos {\n\treturn s.StatementEnd\n}\n\nfunc (s *SystemFlushExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif s.Distributed != nil {\n\t\tif err := s.Distributed.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSystemFlushExpr(s)\n}\n\ntype SystemReloadExpr struct {\n\tReloadPos    Pos\n\tStatementEnd Pos\n\tDictionary   *TableIdentifier\n\tType         string\n}\n\nfunc (s *SystemReloadExpr) Pos() Pos {\n\treturn s.ReloadPos\n}\n\nfunc (s *SystemReloadExpr) End() Pos {\n\treturn s.StatementEnd\n}\n\nfunc (s *SystemReloadExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif s.Dictionary != nil {\n\t\tif err := s.Dictionary.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSystemReloadExpr(s)\n}\n\ntype SystemSyncExpr struct {\n\tSyncPos Pos\n\tCluster *TableIdentifier\n}\n\nfunc (s *SystemSyncExpr) Pos() Pos {\n\treturn s.SyncPos\n}\n\nfunc (s *SystemSyncExpr) End() Pos {\n\treturn s.Cluster.End()\n}\n\nfunc (s *SystemSyncExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Cluster.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitSystemSyncExpr(s)\n}\n\ntype SystemCtrlExpr struct {\n\tCtrlPos      Pos\n\tStatementEnd Pos\n\tCommand      string // START, STOP\n\tType         string // REPLICATED, DISTRIBUTED\n\tCluster      *TableIdentifier\n}\n\nfunc (s *SystemCtrlExpr) Pos() Pos {\n\treturn s.CtrlPos\n}\n\nfunc (s *SystemCtrlExpr) End() Pos {\n\treturn s.StatementEnd\n}\n\nfunc (s *SystemCtrlExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif s.Cluster != nil {\n\t\tif err := s.Cluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSystemCtrlExpr(s)\n}\n\ntype SystemDropExpr struct {\n\tDropPos      Pos\n\tStatementEnd Pos\n\tType         string\n}\n\nfunc (s *SystemDropExpr) Pos() Pos {\n\treturn s.DropPos\n}\n\nfunc (s *SystemDropExpr) End() Pos {\n\treturn s.StatementEnd\n}\n\nfunc (s *SystemDropExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\treturn visitor.VisitSystemDropExpr(s)\n}\n\ntype TruncateTable struct {\n\tTruncatePos  Pos\n\tStatementEnd Pos\n\tIsTemporary  bool\n\tIfExists     bool\n\tName         *TableIdentifier\n\tOnCluster    *ClusterClause\n}\n\nfunc (t *TruncateTable) Pos() Pos {\n\treturn t.TruncatePos\n}\n\nfunc (t *TruncateTable) End() Pos {\n\treturn t.StatementEnd\n}\n\nfunc (t *TruncateTable) Type() string {\n\treturn \"TRUNCATE TABLE\"\n}\n\nfunc (t *TruncateTable) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Name.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif t.OnCluster != nil {\n\t\tif err := t.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitTruncateTable(t)\n}\n\ntype SampleClause struct {\n\tSamplePos Pos\n\tRatio     *RatioExpr\n\tOffset    *RatioExpr\n}\n\nfunc (s *SampleClause) Pos() Pos {\n\treturn s.SamplePos\n}\n\nfunc (s *SampleClause) End() Pos {\n\tif s.Offset != nil {\n\t\treturn s.Offset.End()\n\t}\n\treturn s.Ratio.End()\n}\n\nfunc (s *SampleClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif err := s.Ratio.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif s.Offset != nil {\n\t\tif err := s.Offset.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitSampleRatioExpr(s)\n}\n\ntype DeleteClause struct {\n\tDeletePos Pos\n\tTable     *TableIdentifier\n\tOnCluster *ClusterClause\n\tWhereExpr Expr\n}\n\nfunc (d *DeleteClause) Pos() Pos {\n\treturn d.DeletePos\n}\n\nfunc (d *DeleteClause) End() Pos {\n\treturn d.WhereExpr.End()\n}\n\nfunc (d *DeleteClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif d.OnCluster != nil {\n\t\tif err := d.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif d.WhereExpr != nil {\n\t\tif err := d.WhereExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitDeleteFromExpr(d)\n}\n\ntype ColumnNamesExpr struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tColumnNames   []NestedIdentifier\n}\n\nfunc (c *ColumnNamesExpr) Pos() Pos {\n\treturn c.LeftParenPos\n}\n\nfunc (c *ColumnNamesExpr) End() Pos {\n\treturn c.RightParenPos\n}\n\nfunc (c *ColumnNamesExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tfor i := range c.ColumnNames {\n\t\tif err := c.ColumnNames[i].Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitColumnNamesExpr(c)\n}\n\ntype AssignmentValues struct {\n\tLeftParenPos  Pos\n\tRightParenPos Pos\n\tValues        []Expr\n}\n\nfunc (v *AssignmentValues) Pos() Pos {\n\treturn v.LeftParenPos\n}\n\nfunc (v *AssignmentValues) End() Pos {\n\treturn v.RightParenPos\n}\n\nfunc (v *AssignmentValues) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(v)\n\tdefer visitor.Leave(v)\n\tfor _, value := range v.Values {\n\t\tif err := value.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitValuesExpr(v)\n}\n\ntype InsertStmt struct {\n\tInsertPos       Pos\n\tFormat          *FormatClause\n\tHasTableKeyword bool\n\tTable           Expr\n\tColumnNames     *ColumnNamesExpr\n\tValues          []*AssignmentValues\n\tSelectExpr      *SelectQuery\n}\n\nfunc (i *InsertStmt) Pos() Pos {\n\treturn i.InsertPos\n}\n\nfunc (i *InsertStmt) End() Pos {\n\tif i.SelectExpr != nil {\n\t\treturn i.SelectExpr.End()\n\t}\n\treturn i.Values[len(i.Values)-1].End()\n}\n\nfunc (i *InsertStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(i)\n\tdefer visitor.Leave(i)\n\tif i.Format != nil {\n\t\tif err := i.Format.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := i.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif i.ColumnNames != nil {\n\t\tif err := i.ColumnNames.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, value := range i.Values {\n\t\tif err := value.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif i.SelectExpr != nil {\n\t\tif err := i.SelectExpr.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitInsertExpr(i)\n}\n\ntype CheckStmt struct {\n\tCheckPos  Pos\n\tTable     *TableIdentifier\n\tPartition *PartitionClause\n}\n\nfunc (c *CheckStmt) Pos() Pos {\n\treturn c.CheckPos\n}\n\nfunc (c *CheckStmt) End() Pos {\n\treturn c.Partition.End()\n}\n\nfunc (c *CheckStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(c)\n\tdefer visitor.Leave(c)\n\tif err := c.Table.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif c.Partition != nil {\n\t\tif err := c.Partition.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitCheckExpr(c)\n}\n\ntype UnaryExpr struct {\n\tUnaryPos Pos\n\tKind     TokenKind\n\tExpr     Expr\n}\n\nfunc (n *UnaryExpr) Pos() Pos {\n\treturn n.UnaryPos\n}\n\nfunc (n *UnaryExpr) End() Pos {\n\treturn n.Expr.End()\n}\n\nfunc (n *UnaryExpr) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(n)\n\tdefer visitor.Leave(n)\n\tif err := n.Expr.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitUnaryExpr(n)\n}\n\ntype RenameStmt struct {\n\tRenamePos    Pos\n\tStatementEnd Pos\n\n\tRenameTarget   string\n\tTargetPairList []*TargetPair\n\tOnCluster      *ClusterClause\n}\n\nfunc (r *RenameStmt) Pos() Pos {\n\treturn r.RenamePos\n}\n\nfunc (r *RenameStmt) End() Pos {\n\treturn r.StatementEnd\n}\n\nfunc (r *RenameStmt) Type() string {\n\treturn \"RENAME \" + r.RenameTarget\n}\n\nfunc (r *RenameStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(r)\n\tdefer visitor.Leave(r)\n\tfor _, pair := range r.TargetPairList {\n\t\tif err := pair.Old.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := pair.New.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif r.OnCluster != nil {\n\t\tif err := r.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitRenameStmt(r)\n}\n\ntype TargetPair struct {\n\tOld *TableIdentifier\n\tNew *TableIdentifier\n}\n\nfunc (t *TargetPair) Pos() Pos {\n\treturn t.Old.Pos()\n}\n\nfunc (t *TargetPair) End() Pos {\n\treturn t.New.End()\n}\n\nfunc (t *TargetPair) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(t)\n\tdefer visitor.Leave(t)\n\tif err := t.Old.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tif err := t.New.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitTargetPairExpr(t)\n}\n\ntype ExplainStmt struct {\n\tExplainPos Pos\n\tType       string\n\tStatement  Expr\n}\n\nfunc (e *ExplainStmt) Pos() Pos {\n\treturn e.ExplainPos\n}\n\nfunc (e *ExplainStmt) End() Pos {\n\treturn e.Statement.End()\n}\n\nfunc (e *ExplainStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(e)\n\tdefer visitor.Leave(e)\n\tif err := e.Statement.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitExplainExpr(e)\n}\n\ntype PrivilegeClause struct {\n\tPrivilegePos Pos\n\tPrivilegeEnd Pos\n\tKeywords     []string\n\tParams       *ParamExprList\n}\n\nfunc (p *PrivilegeClause) Pos() Pos {\n\treturn p.PrivilegePos\n}\n\nfunc (p *PrivilegeClause) End() Pos {\n\treturn p.PrivilegeEnd\n}\n\nfunc (p *PrivilegeClause) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(p)\n\tdefer visitor.Leave(p)\n\tif p.Params != nil {\n\t\tif err := p.Params.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitPrivilegeExpr(p)\n}\n\ntype GrantPrivilegeStmt struct {\n\tGrantPos     Pos\n\tStatementEnd Pos\n\tOnCluster    *ClusterClause\n\tPrivileges   []*PrivilegeClause\n\tOn           *TableIdentifier\n\tTo           []*Ident\n\tWithOptions  []string\n}\n\nfunc (g *GrantPrivilegeStmt) Pos() Pos {\n\treturn g.GrantPos\n}\n\nfunc (g *GrantPrivilegeStmt) End() Pos {\n\treturn g.StatementEnd\n}\n\nfunc (g *GrantPrivilegeStmt) Type() string {\n\treturn \"GRANT PRIVILEGE\"\n}\n\nfunc (g *GrantPrivilegeStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(g)\n\tdefer visitor.Leave(g)\n\tif g.OnCluster != nil {\n\t\tif err := g.OnCluster.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, privilege := range g.Privileges {\n\t\tif err := privilege.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := g.On.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\tfor _, role := range g.To {\n\t\tif err := role.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitGrantPrivilegeExpr(g)\n}\n\ntype ShowStmt struct {\n\tShowPos      Pos\n\tStatementEnd Pos\n\tShowType     string           // e.g., \"CREATE TABLE\", \"DATABASES\", \"TABLES\"\n\tTarget       *TableIdentifier // for SHOW CREATE TABLE table_name\n\n\t// Optional clauses for SHOW DATABASES\n\tNotLike     bool           // true if NOT LIKE/ILIKE\n\tLikeType    string         // \"LIKE\" or \"ILIKE\", empty if not used\n\tLikePattern Expr           // pattern expression for LIKE/ILIKE\n\tLimit       Expr           // limit expression\n\tOutFile     *StringLiteral // filename for INTO OUTFILE\n\tFormat      *StringLiteral // format specification\n}\n\nfunc (s *ShowStmt) Pos() Pos {\n\treturn s.ShowPos\n}\n\nfunc (s *ShowStmt) End() Pos {\n\t// Find the rightmost element to determine the end position\n\tif s.Format != nil {\n\t\treturn s.Format.End()\n\t}\n\tif s.OutFile != nil {\n\t\treturn s.OutFile.End()\n\t}\n\tif s.Limit != nil {\n\t\treturn s.Limit.End()\n\t}\n\tif s.LikePattern != nil {\n\t\treturn s.LikePattern.End()\n\t}\n\tif s.Target != nil {\n\t\treturn s.Target.End()\n\t}\n\treturn s.StatementEnd\n}\n\nfunc (s *ShowStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(s)\n\tdefer visitor.Leave(s)\n\tif s.Target != nil {\n\t\tif err := s.Target.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.LikePattern != nil {\n\t\tif err := s.LikePattern.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Limit != nil {\n\t\tif err := s.Limit.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.OutFile != nil {\n\t\tif err := s.OutFile.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif s.Format != nil {\n\t\tif err := s.Format.Accept(visitor); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn visitor.VisitShowExpr(s)\n}\n\ntype DescribeStmt struct {\n\tDescribePos  Pos\n\tStatementEnd Pos\n\tDescribeType string // e.g., \"TABLE\", empty if not used\n\tTarget       *TableIdentifier\n}\n\nfunc (d *DescribeStmt) Pos() Pos {\n\treturn d.DescribePos\n}\n\nfunc (d *DescribeStmt) End() Pos {\n\treturn d.Target.End()\n}\n\nfunc (d *DescribeStmt) Accept(visitor ASTVisitor) error {\n\tvisitor.Enter(d)\n\tdefer visitor.Leave(d)\n\tif err := d.Target.Accept(visitor); err != nil {\n\t\treturn err\n\t}\n\treturn visitor.VisitDescribeExpr(d)\n}\n"
  },
  {
    "path": "parser/ast_visitor.go",
    "content": "package parser\n\ntype ASTVisitor interface {\n\tVisitOperationExpr(expr *OperationExpr) error\n\tVisitTernaryExpr(expr *TernaryOperation) error\n\tVisitBinaryExpr(expr *BinaryOperation) error\n\tVisitIndexOperation(expr *IndexOperation) error\n\tVisitAlterTable(expr *AlterTable) error\n\tVisitAlterTableAttachPartition(expr *AlterTableAttachPartition) error\n\tVisitAlterTableDetachPartition(expr *AlterTableDetachPartition) error\n\tVisitAlterTableDropPartition(expr *AlterTableDropPartition) error\n\tVisitAlterTableFreezePartition(expr *AlterTableFreezePartition) error\n\tVisitAlterTableAddColumn(expr *AlterTableAddColumn) error\n\tVisitAlterTableAddIndex(expr *AlterTableAddIndex) error\n\tVisitAlterTableAddProjection(expr *AlterTableAddProjection) error\n\tVisitTableProjection(expr *TableProjection) error\n\tVisitProjectionOrderBy(expr *ProjectionOrderByClause) error\n\tVisitProjectionSelect(expr *ProjectionSelectStmt) error\n\tVisitAlterTableDropColumn(expr *AlterTableDropColumn) error\n\tVisitAlterTableDropIndex(expr *AlterTableDropIndex) error\n\tVisitAlterTableDropProjection(expr *AlterTableDropProjection) error\n\tVisitAlterTableRemoveTTL(expr *AlterTableRemoveTTL) error\n\tVisitAlterTableClearColumn(expr *AlterTableClearColumn) error\n\tVisitAlterTableClearIndex(expr *AlterTableClearIndex) error\n\tVisitAlterTableClearProjection(expr *AlterTableClearProjection) error\n\tVisitAlterTableMaterializeIndex(expr *AlterTableMaterializeIndex) error\n\tVisitAlterTableMaterializeProjection(expr *AlterTableMaterializeProjection) error\n\tVisitAlterTableRenameColumn(expr *AlterTableRenameColumn) error\n\tVisitAlterTableModifyTTL(expr *AlterTableModifyTTL) error\n\tVisitAlterTableModifyQuery(expr *AlterTableModifyQuery) error\n\tVisitAlterTableModifyColumn(expr *AlterTableModifyColumn) error\n\tVisitAlterTableModifySetting(expr *AlterTableModifySetting) error\n\tVisitAlterTableResetSetting(expr *AlterTableResetSetting) error\n\tVisitAlterTableReplacePartition(expr *AlterTableReplacePartition) error\n\tVisitAlterTableDelete(expr *AlterTableDelete) error\n\tVisitAlterTableUpdate(expr *AlterTableUpdate) error\n\tVisitUpdateAssignment(expr *UpdateAssignment) error\n\tVisitRemovePropertyType(expr *RemovePropertyType) error\n\tVisitTableIndex(expr *TableIndex) error\n\tVisitIdent(expr *Ident) error\n\tVisitUUID(expr *UUID) error\n\tVisitCreateDatabase(expr *CreateDatabase) error\n\tVisitCreateTable(expr *CreateTable) error\n\tVisitCreateMaterializedView(expr *CreateMaterializedView) error\n\tVisitCreateView(expr *CreateView) error\n\tVisitCreateFunction(expr *CreateFunction) error\n\tVisitRoleName(expr *RoleName) error\n\tVisitSettingPair(expr *SettingPair) error\n\tVisitRoleSetting(expr *RoleSetting) error\n\tVisitCreateRole(expr *CreateRole) error\n\tVisitCreateUser(expr *CreateUser) error\n\tVisitAuthenticationClause(expr *AuthenticationClause) error\n\tVisitHostClause(expr *HostClause) error\n\tVisitDefaultRoleClause(expr *DefaultRoleClause) error\n\tVisitGranteesClause(expr *GranteesClause) error\n\tVisitAlterRole(expr *AlterRole) error\n\tVisitRoleRenamePair(expr *RoleRenamePair) error\n\tVisitDestinationExpr(expr *DestinationClause) error\n\tVisitConstraintExpr(expr *ConstraintClause) error\n\tVisitNullLiteral(expr *NullLiteral) error\n\tVisitNotNullLiteral(expr *NotNullLiteral) error\n\tVisitPath(expr *Path) error\n\tVisitNestedIdentifier(expr *NestedIdentifier) error\n\tVisitTableIdentifier(expr *TableIdentifier) error\n\tVisitTableSchemaExpr(expr *TableSchemaClause) error\n\tVisitTableArgListExpr(expr *TableArgListExpr) error\n\tVisitTableFunctionExpr(expr *TableFunctionExpr) error\n\tVisitOnClusterExpr(expr *ClusterClause) error\n\tVisitPartitionExpr(expr *PartitionClause) error\n\tVisitPartitionByExpr(expr *PartitionByClause) error\n\tVisitPrimaryKeyExpr(expr *PrimaryKeyClause) error\n\tVisitSampleByExpr(expr *SampleByClause) error\n\tVisitTTLExpr(expr *TTLExpr) error\n\tVisitTTLExprList(expr *TTLClause) error\n\tVisitTTLPolicy(expr *TTLPolicy) error\n\tVisitTTLPolicyRule(expr *TTLPolicyRule) error\n\tVisitTTLPolicyItemAction(expr *TTLPolicyRuleAction) error\n\tVisitRefreshExpr(expr *RefreshExpr) error\n\tVisitOrderByExpr(expr *OrderExpr) error\n\tVisitOrderByListExpr(expr *OrderByClause) error\n\tVisitFill(expr *Fill) error\n\tVisitInterpolateItem(expr *InterpolateItem) error\n\tVisitInterpolateClause(expr *InterpolateClause) error\n\tVisitSettingsExpr(expr *SettingExpr) error\n\tVisitSettingsExprList(expr *SettingsClause) error\n\tVisitParamExprList(expr *ParamExprList) error\n\tVisitMapLiteral(expr *MapLiteral) error\n\tVisitNamedParameterExpr(expr *NamedParameterExpr) error\n\tVisitArrayParamList(expr *ArrayParamList) error\n\tVisitQueryParam(expr *QueryParam) error\n\tVisitObjectParams(expr *ObjectParams) error\n\tVisitFunctionExpr(expr *FunctionExpr) error\n\tVisitWindowFunctionExpr(expr *WindowFunctionExpr) error\n\tVisitColumnDef(expr *ColumnDef) error\n\tVisitColumnExpr(expr *ColumnExpr) error\n\tVisitTypedPlaceholder(expr *TypedPlaceholder) error\n\tVisitScalarType(expr *ScalarType) error\n\tVisitJSONType(expr *JSONType) error\n\tVisitPropertyType(expr *PropertyType) error\n\tVisitTypeWithParams(expr *TypeWithParams) error\n\tVisitComplexType(expr *ComplexType) error\n\tVisitNestedType(expr *NestedType) error\n\tVisitCompressionCodec(expr *CompressionCodec) error\n\tVisitNumberLiteral(expr *NumberLiteral) error\n\tVisitStringLiteral(expr *StringLiteral) error\n\tVisitRatioExpr(expr *RatioExpr) error\n\tVisitEnumValue(expr *EnumValue) error\n\tVisitEnumType(expr *EnumType) error\n\tVisitIntervalExpr(expr *IntervalExpr) error\n\tVisitEngineExpr(expr *EngineExpr) error\n\tVisitColumnTypeExpr(expr *ColumnTypeExpr) error\n\tVisitColumnArgList(expr *ColumnArgList) error\n\tVisitColumnExprList(expr *ColumnExprList) error\n\tVisitWhenExpr(expr *WhenClause) error\n\tVisitCaseExpr(expr *CaseExpr) error\n\tVisitCastExpr(expr *CastExpr) error\n\tVisitWithExpr(expr *WithClause) error\n\tVisitTopExpr(expr *TopClause) error\n\tVisitCreateLiveView(expr *CreateLiveView) error\n\tVisitCreateDictionary(expr *CreateDictionary) error\n\tVisitCreateNamedCollection(expr *CreateNamedCollection) error\n\tVisitNamedCollectionParam(expr *NamedCollectionParam) error\n\tVisitDictionarySchemaClause(expr *DictionarySchemaClause) error\n\tVisitDictionaryAttribute(expr *DictionaryAttribute) error\n\tVisitDictionaryEngineClause(expr *DictionaryEngineClause) error\n\tVisitDictionaryPrimaryKeyClause(expr *DictionaryPrimaryKeyClause) error\n\tVisitDictionarySourceClause(expr *DictionarySourceClause) error\n\tVisitDictionaryArgExpr(expr *DictionaryArgExpr) error\n\tVisitDictionaryLifetimeClause(expr *DictionaryLifetimeClause) error\n\tVisitDictionaryLayoutClause(expr *DictionaryLayoutClause) error\n\tVisitDictionaryRangeClause(expr *DictionaryRangeClause) error\n\tVisitWithTimeoutExpr(expr *WithTimeoutClause) error\n\tVisitTableExpr(expr *TableExpr) error\n\tVisitOnExpr(expr *OnClause) error\n\tVisitUsingExpr(expr *UsingClause) error\n\tVisitJoinExpr(expr *JoinExpr) error\n\tVisitJoinConstraintExpr(expr *JoinConstraintClause) error\n\tVisitJoinTableExpr(expr *JoinTableExpr) error\n\tVisitFromExpr(expr *FromClause) error\n\tVisitIsNullExpr(expr *IsNullExpr) error\n\tVisitIsNotNullExpr(expr *IsNotNullExpr) error\n\tVisitAliasExpr(expr *AliasExpr) error\n\tVisitWhereExpr(expr *WhereClause) error\n\tVisitPrewhereExpr(expr *PrewhereClause) error\n\tVisitGroupByExpr(expr *GroupByClause) error\n\tVisitHavingExpr(expr *HavingClause) error\n\tVisitLimitExpr(expr *LimitClause) error\n\tVisitLimitByExpr(expr *LimitByClause) error\n\tVisitWindowConditionExpr(expr *WindowExpr) error\n\tVisitWindowExpr(expr *WindowClause) error\n\tVisitWindowFrameExpr(expr *WindowFrameClause) error\n\tVisitWindowFrameExtendExpr(expr *WindowFrameExtendExpr) error\n\tVisitBetweenClause(expr *BetweenClause) error\n\tVisitWindowFrameCurrentRow(expr *WindowFrameCurrentRow) error\n\tVisitWindowFrameUnbounded(expr *WindowFrameUnbounded) error\n\tVisitWindowFrameNumber(expr *WindowFrameNumber) error\n\tVisitWindowFrameParam(expr *WindowFrameParam) error\n\tVisitSelectQuery(expr *SelectQuery) error\n\tVisitSubQueryExpr(expr *SubQuery) error\n\tVisitNotExpr(expr *NotExpr) error\n\tVisitNegateExpr(expr *NegateExpr) error\n\tVisitGlobalInExpr(expr *GlobalInOperation) error\n\tVisitExtractExpr(expr *ExtractExpr) error\n\tVisitIntervalFrom(expr *IntervalFrom) error\n\tVisitDropDatabase(expr *DropDatabase) error\n\tVisitDropStmt(expr *DropStmt) error\n\tVisitDropUserOrRole(expr *DropUserOrRole) error\n\tVisitUseExpr(expr *UseStmt) error\n\tVisitCTEExpr(expr *CTEStmt) error\n\tVisitSetExpr(expr *SetStmt) error\n\tVisitFormatExpr(expr *FormatClause) error\n\tVisitOptimizeExpr(expr *OptimizeStmt) error\n\tVisitDeduplicateExpr(expr *DeduplicateClause) error\n\tVisitSystemExpr(expr *SystemStmt) error\n\tVisitSystemFlushExpr(expr *SystemFlushExpr) error\n\tVisitSystemReloadExpr(expr *SystemReloadExpr) error\n\tVisitSystemSyncExpr(expr *SystemSyncExpr) error\n\tVisitSystemCtrlExpr(expr *SystemCtrlExpr) error\n\tVisitSystemDropExpr(expr *SystemDropExpr) error\n\tVisitTruncateTable(expr *TruncateTable) error\n\tVisitSampleRatioExpr(expr *SampleClause) error\n\tVisitPlaceHolderExpr(expr *PlaceHolder) error\n\tVisitDeleteFromExpr(expr *DeleteClause) error\n\tVisitColumnNamesExpr(expr *ColumnNamesExpr) error\n\tVisitValuesExpr(expr *AssignmentValues) error\n\tVisitInsertExpr(expr *InsertStmt) error\n\tVisitCheckExpr(expr *CheckStmt) error\n\tVisitUnaryExpr(expr *UnaryExpr) error\n\tVisitRenameStmt(expr *RenameStmt) error\n\tVisitExplainExpr(expr *ExplainStmt) error\n\tVisitPrivilegeExpr(expr *PrivilegeClause) error\n\tVisitGrantPrivilegeExpr(expr *GrantPrivilegeStmt) error\n\tVisitShowExpr(expr *ShowStmt) error\n\tVisitDescribeExpr(expr *DescribeStmt) error\n\tVisitSelectItem(expr *SelectItem) error\n\tVisitTargetPairExpr(expr *TargetPair) error\n\tVisitDistinctOn(expr *DistinctOn) error\n\tVisitBoolLiteral(expr *BoolLiteral) error\n\n\tEnter(expr Expr)\n\tLeave(expr Expr)\n}\n\ntype VisitFunc func(expr Expr) error\n\ntype DefaultASTVisitor struct {\n\tVisit VisitFunc\n}\n\nfunc (v *DefaultASTVisitor) VisitOperationExpr(expr *OperationExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTernaryExpr(expr *TernaryOperation) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitBinaryExpr(expr *BinaryOperation) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitIndexOperation(expr *IndexOperation) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitJoinTableExpr(expr *JoinTableExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTable(expr *AlterTable) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableAttachPartition(expr *AlterTableAttachPartition) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableDetachPartition(expr *AlterTableDetachPartition) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableDropPartition(expr *AlterTableDropPartition) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableFreezePartition(expr *AlterTableFreezePartition) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableAddColumn(expr *AlterTableAddColumn) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableAddIndex(expr *AlterTableAddIndex) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableAddProjection(expr *AlterTableAddProjection) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitProjectionOrderBy(expr *ProjectionOrderByClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitProjectionSelect(expr *ProjectionSelectStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableProjection(expr *TableProjection) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableDropColumn(expr *AlterTableDropColumn) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableDropIndex(expr *AlterTableDropIndex) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableDropProjection(expr *AlterTableDropProjection) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableRemoveTTL(expr *AlterTableRemoveTTL) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableClearColumn(expr *AlterTableClearColumn) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableClearIndex(expr *AlterTableClearIndex) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableClearProjection(expr *AlterTableClearProjection) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableMaterializeProjection(expr *AlterTableMaterializeProjection) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableMaterializeIndex(expr *AlterTableMaterializeIndex) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableRenameColumn(expr *AlterTableRenameColumn) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableModifyQuery(expr *AlterTableModifyQuery) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableModifyTTL(expr *AlterTableModifyTTL) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableModifyColumn(expr *AlterTableModifyColumn) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableModifySetting(expr *AlterTableModifySetting) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableResetSetting(expr *AlterTableResetSetting) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableReplacePartition(expr *AlterTableReplacePartition) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableDelete(expr *AlterTableDelete) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterTableUpdate(expr *AlterTableUpdate) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitUpdateAssignment(expr *UpdateAssignment) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRemovePropertyType(expr *RemovePropertyType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableIndex(expr *TableIndex) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitIdent(expr *Ident) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitUUID(expr *UUID) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateDatabase(expr *CreateDatabase) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateTable(expr *CreateTable) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateMaterializedView(expr *CreateMaterializedView) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateView(expr *CreateView) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateFunction(expr *CreateFunction) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRoleName(expr *RoleName) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSettingPair(expr *SettingPair) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRoleSetting(expr *RoleSetting) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateRole(expr *CreateRole) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateUser(expr *CreateUser) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAuthenticationClause(expr *AuthenticationClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitHostClause(expr *HostClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDefaultRoleClause(expr *DefaultRoleClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitGranteesClause(expr *GranteesClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAlterRole(expr *AlterRole) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRoleRenamePair(expr *RoleRenamePair) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDestinationExpr(expr *DestinationClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitConstraintExpr(expr *ConstraintClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNullLiteral(expr *NullLiteral) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNotNullLiteral(expr *NotNullLiteral) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNestedIdentifier(expr *NestedIdentifier) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPath(expr *Path) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableIdentifier(expr *TableIdentifier) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableSchemaExpr(expr *TableSchemaClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableArgListExpr(expr *TableArgListExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableFunctionExpr(expr *TableFunctionExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitOnClusterExpr(expr *ClusterClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPartitionExpr(expr *PartitionClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPartitionByExpr(expr *PartitionByClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPrimaryKeyExpr(expr *PrimaryKeyClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSampleByExpr(expr *SampleByClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTTLExpr(expr *TTLExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTTLExprList(expr *TTLClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTTLPolicy(expr *TTLPolicy) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTTLPolicyRule(expr *TTLPolicyRule) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTTLPolicyItemAction(expr *TTLPolicyRuleAction) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRefreshExpr(expr *RefreshExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitOrderByExpr(expr *OrderExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitOrderByListExpr(expr *OrderByClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitFill(expr *Fill) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitInterpolateItem(expr *InterpolateItem) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitInterpolateClause(expr *InterpolateClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSettingsExpr(expr *SettingExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSettingsExprList(expr *SettingsClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitParamExprList(expr *ParamExprList) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitArrayParamList(expr *ArrayParamList) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitQueryParam(expr *QueryParam) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitMapLiteral(expr *MapLiteral) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNamedParameterExpr(expr *NamedParameterExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitObjectParams(expr *ObjectParams) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitFunctionExpr(expr *FunctionExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFunctionExpr(expr *WindowFunctionExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitColumnDef(expr *ColumnDef) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitColumnExpr(expr *ColumnExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTypedPlaceholder(expr *TypedPlaceholder) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitScalarType(expr *ScalarType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitJSONType(expr *JSONType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPropertyType(expr *PropertyType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTypeWithParams(expr *TypeWithParams) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitComplexType(expr *ComplexType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNestedType(expr *NestedType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCompressionCodec(expr *CompressionCodec) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNumberLiteral(expr *NumberLiteral) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitStringLiteral(expr *StringLiteral) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRatioExpr(expr *RatioExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitEnumValue(expr *EnumValue) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitEnumType(expr *EnumType) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitIntervalExpr(expr *IntervalExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitEngineExpr(expr *EngineExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitColumnTypeExpr(expr *ColumnTypeExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitColumnArgList(expr *ColumnArgList) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitColumnExprList(expr *ColumnExprList) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWhenExpr(expr *WhenClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCaseExpr(expr *CaseExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCastExpr(expr *CastExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWithExpr(expr *WithClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTopExpr(expr *TopClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateLiveView(expr *CreateLiveView) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateDictionary(expr *CreateDictionary) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCreateNamedCollection(expr *CreateNamedCollection) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNamedCollectionParam(expr *NamedCollectionParam) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionarySchemaClause(expr *DictionarySchemaClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryAttribute(expr *DictionaryAttribute) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryEngineClause(expr *DictionaryEngineClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryPrimaryKeyClause(expr *DictionaryPrimaryKeyClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionarySourceClause(expr *DictionarySourceClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryArgExpr(expr *DictionaryArgExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryLifetimeClause(expr *DictionaryLifetimeClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryLayoutClause(expr *DictionaryLayoutClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDictionaryRangeClause(expr *DictionaryRangeClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWithTimeoutExpr(expr *WithTimeoutClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTableExpr(expr *TableExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitOnExpr(expr *OnClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitUsingExpr(expr *UsingClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitJoinExpr(expr *JoinExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitJoinConstraintExpr(expr *JoinConstraintClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitFromExpr(expr *FromClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitIsNullExpr(expr *IsNullExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitIsNotNullExpr(expr *IsNotNullExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitAliasExpr(expr *AliasExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWhereExpr(expr *WhereClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPrewhereExpr(expr *PrewhereClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitGroupByExpr(expr *GroupByClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitHavingExpr(expr *HavingClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitLimitExpr(expr *LimitClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitLimitByExpr(expr *LimitByClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowConditionExpr(expr *WindowExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowExpr(expr *WindowClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFrameExpr(expr *WindowFrameClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFrameExtendExpr(expr *WindowFrameExtendExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitBetweenClause(expr *BetweenClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFrameCurrentRow(expr *WindowFrameCurrentRow) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFrameUnbounded(expr *WindowFrameUnbounded) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFrameNumber(expr *WindowFrameNumber) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitWindowFrameParam(expr *WindowFrameParam) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSelectQuery(expr *SelectQuery) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSubQueryExpr(expr *SubQuery) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNotExpr(expr *NotExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitNegateExpr(expr *NegateExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitGlobalInExpr(expr *GlobalInOperation) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitExtractExpr(expr *ExtractExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitIntervalFrom(expr *IntervalFrom) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDropDatabase(expr *DropDatabase) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDropStmt(expr *DropStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDropUserOrRole(expr *DropUserOrRole) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitUseExpr(expr *UseStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCTEExpr(expr *CTEStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSetExpr(expr *SetStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitFormatExpr(expr *FormatClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitOptimizeExpr(expr *OptimizeStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDeduplicateExpr(expr *DeduplicateClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSystemExpr(expr *SystemStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSystemFlushExpr(expr *SystemFlushExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSystemReloadExpr(expr *SystemReloadExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSystemSyncExpr(expr *SystemSyncExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSystemCtrlExpr(expr *SystemCtrlExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSystemDropExpr(expr *SystemDropExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTruncateTable(expr *TruncateTable) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSampleRatioExpr(expr *SampleClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPlaceHolderExpr(expr *PlaceHolder) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDeleteFromExpr(expr *DeleteClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitColumnNamesExpr(expr *ColumnNamesExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitValuesExpr(expr *AssignmentValues) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitInsertExpr(expr *InsertStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitCheckExpr(expr *CheckStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitUnaryExpr(expr *UnaryExpr) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitRenameStmt(expr *RenameStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitExplainExpr(expr *ExplainStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitPrivilegeExpr(expr *PrivilegeClause) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitGrantPrivilegeExpr(expr *GrantPrivilegeStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitShowExpr(expr *ShowStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDescribeExpr(expr *DescribeStmt) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitSelectItem(expr *SelectItem) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitTargetPairExpr(expr *TargetPair) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitDistinctOn(expr *DistinctOn) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) VisitBoolLiteral(expr *BoolLiteral) error {\n\tif v.Visit != nil {\n\t\treturn v.Visit(expr)\n\t}\n\treturn nil\n}\n\nfunc (v *DefaultASTVisitor) Enter(expr Expr) {}\n\nfunc (v *DefaultASTVisitor) Leave(expr Expr) {}\n"
  },
  {
    "path": "parser/benchmark_test.go",
    "content": "package parser\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n)\n\n// BenchmarkParseSQLFiles benchmarks parsing all SQL files in the testdata/query directory\nfunc BenchmarkParseSQLFiles(b *testing.B) {\n\ttestFiles, err := filepath.Glob(\"testdata/query/*.sql\")\n\tif err != nil {\n\t\tb.Fatalf(\"Failed to glob test files: %v\", err)\n\t}\n\n\tfor _, file := range testFiles {\n\t\tcontent, err := os.ReadFile(file)\n\t\tif err != nil {\n\t\t\tb.Fatalf(\"Failed to read file %s: %v\", file, err)\n\t\t}\n\n\t\tb.Run(filepath.Base(file), func(b *testing.B) {\n\t\t\tfor i := 0; i < b.N; i++ {\n\t\t\t\tparser := NewParser(string(content))\n\t\t\t\t_, err := parser.ParseStmts()\n\t\t\t\tif err != nil {\n\t\t\t\t\tb.Fatalf(\"Failed to parse SQL from %s: %v\", file, err)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\n// BenchmarkParseComplexQueries benchmarks parsing specifically complex SQL queries\nfunc BenchmarkParseComplexQueries(b *testing.B) {\n\tcomplexQueries := []string{\n\t\t\"testdata/query/select_with_multi_join.sql\",\n\t\t\"testdata/query/select_with_window_function.sql\",\n\t\t\"testdata/query/select_simple_with_with_clause.sql\",\n\t\t\"testdata/query/select_with_left_join.sql\",\n\t\t\"testdata/benchdata/posthog_huge_0.sql\",\n\t\t\"testdata/benchdata/posthog_huge_1.sql\",\n\t}\n\n\tfor _, queryFile := range complexQueries {\n\t\tcontent, err := os.ReadFile(queryFile)\n\t\tif err != nil {\n\t\t\tb.Fatalf(\"Failed to read file %s: %v\", queryFile, err)\n\t\t}\n\n\t\tb.Run(queryFile, func(b *testing.B) {\n\t\t\tb.ResetTimer()\n\t\t\tfor i := 0; i < b.N; i++ {\n\t\t\t\tparser := NewParser(string(content))\n\t\t\t\t_, err := parser.ParseStmts()\n\t\t\t\tif err != nil {\n\t\t\t\t\tb.Fatalf(\"Failed to parse SQL from %s: %v\", queryFile, err)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/format.go",
    "content": "package parser\n\nimport \"strings\"\n\nconst (\n\twhitespace byte = ' '\n\tnewline    byte = '\\n'\n)\n\ntype FormatMode int\n\nconst (\n\tFormatModeCompact FormatMode = iota + 1\n\tFormatModeBeautify\n)\n\n// Formatter renders SQL.\ntype Formatter struct {\n\tbuilder strings.Builder\n\n\tmode        FormatMode\n\tindentLevel int\n\tlineStart   bool\n\tindent      string\n}\n\nfunc NewFormatter() *Formatter {\n\treturn &Formatter{\n\t\tmode:      FormatModeCompact,\n\t\tlineStart: true,\n\t\tindent:    \"  \",\n\t}\n}\n\nfunc (f *Formatter) WithBeautify() *Formatter {\n\tf.mode = FormatModeBeautify\n\treturn f\n}\n\n// WithIndent sets the indentation string used when beautifying SQL.\n// The indent parameter should not be empty to maintain proper formatting.\nfunc (f *Formatter) WithIndent(indent string) *Formatter {\n\tf.indent = indent\n\treturn f\n}\n\nfunc (f *Formatter) writeIndentIfNeeded() {\n\tif !f.lineStart {\n\t\treturn\n\t}\n\tfor i := 0; i < f.indentLevel; i++ {\n\t\tf.builder.WriteString(f.indent)\n\t}\n\tf.lineStart = false\n}\n\nfunc (f *Formatter) WriteString(s string) {\n\tfor i := 0; i < len(s); i++ {\n\t\tf.WriteByte(s[i])\n\t}\n}\n\nfunc (f *Formatter) WriteByte(b byte) {\n\tif f.mode == FormatModeBeautify {\n\t\tif b == newline {\n\t\t\tf.builder.WriteByte(newline)\n\t\t\tf.lineStart = true\n\t\t\treturn\n\t\t}\n\t\tf.writeIndentIfNeeded()\n\t\tf.builder.WriteByte(b)\n\t} else {\n\t\tf.builder.WriteByte(b)\n\t}\n}\n\nfunc (f *Formatter) WriteExpr(expr Expr) {\n\tif expr == nil {\n\t\treturn\n\t}\n\texpr.FormatSQL(f)\n}\n\nfunc (f *Formatter) NewLine() {\n\tif f.mode != FormatModeBeautify {\n\t\treturn\n\t}\n\tf.WriteByte(newline)\n}\n\nfunc (f *Formatter) Break() {\n\tif f.mode == FormatModeBeautify {\n\t\tf.NewLine()\n\t\treturn\n\t}\n\tf.WriteByte(whitespace)\n}\n\nfunc (f *Formatter) Indent() {\n\tf.indentLevel++\n}\n\nfunc (f *Formatter) Dedent() {\n\tif f.indentLevel > 0 {\n\t\tf.indentLevel--\n\t}\n}\n\nfunc (f *Formatter) String() string {\n\treturn f.builder.String()\n}\n\n// Format renders an expression into compact SQL.\nfunc Format(expr Expr) string {\n\tformatter := NewFormatter()\n\tformatter.WriteExpr(expr)\n\treturn formatter.String()\n}\n\nfunc (p *BinaryOperation) isLogicalOp() bool {\n\tswitch p.Operation {\n\tcase TokenKind(KeywordAnd), TokenKind(KeywordOr):\n\t\treturn true\n\tdefault:\n\t\treturn p.HasGlobal || p.HasNot\n\t}\n}\n\nfunc isLogicalBinaryOp(expr Expr) bool {\n\tif bin, ok := expr.(*BinaryOperation); ok {\n\t\treturn bin.isLogicalOp()\n\t}\n\treturn false\n}\n\nfunc (p *BinaryOperation) writeLogicalOperand(formatter *Formatter, expr Expr) {\n\tif isLogicalBinaryOp(expr) {\n\t\tformatter.WriteExpr(expr)\n\t} else {\n\t\tformatter.Indent()\n\t\tformatter.WriteExpr(expr)\n\t\tformatter.Dedent()\n\t}\n}\n\nfunc (p *BinaryOperation) FormatSQL(formatter *Formatter) {\n\tif p.isLogicalOp() && formatter.mode == FormatModeBeautify {\n\t\tp.writeLogicalOperand(formatter, p.LeftExpr)\n\t\tformatter.NewLine()\n\t\tif p.HasNot {\n\t\t\tformatter.WriteString(\"NOT \")\n\t\t} else if p.HasGlobal {\n\t\t\tformatter.WriteString(\"GLOBAL \")\n\t\t}\n\t\tformatter.WriteString(string(p.Operation))\n\t\tformatter.NewLine()\n\t\tp.writeLogicalOperand(formatter, p.RightExpr)\n\t\treturn\n\t}\n\tformatter.WriteExpr(p.LeftExpr)\n\tif p.Operation != TokenKindDash {\n\t\tformatter.WriteByte(whitespace)\n\t}\n\tif p.HasNot {\n\t\tformatter.WriteString(\"NOT \")\n\t} else if p.HasGlobal {\n\t\tformatter.WriteString(\"GLOBAL \")\n\t}\n\tformatter.WriteString(string(p.Operation))\n\tif p.Operation != TokenKindDash {\n\t\tformatter.WriteByte(whitespace)\n\t}\n\tformatter.WriteExpr(p.RightExpr)\n}\n\nfunc (a *AliasExpr) FormatSQL(formatter *Formatter) {\n\tif _, isSelect := a.Expr.(*SelectQuery); isSelect {\n\t\tformatter.WriteByte('(')\n\t\tformatter.WriteExpr(a.Expr)\n\t\tformatter.WriteByte(')')\n\t} else {\n\t\tformatter.WriteExpr(a.Expr)\n\t}\n\tformatter.WriteString(\" AS \")\n\tformatter.WriteExpr(a.Alias)\n}\n\nfunc (a *AlterRole) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ALTER ROLE \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tfor i, roleRenamePair := range a.RoleRenamePairs {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(roleRenamePair)\n\t}\n\tif len(a.Settings) > 0 {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"SETTINGS\")\n\t\tformatter.Indent()\n\t\tfor i, setting := range a.Settings {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\",\")\n\t\t\t}\n\t\t\tformatter.Break()\n\t\t\tformatter.WriteExpr(setting)\n\t\t}\n\t\tformatter.Dedent()\n\t}\n}\n\nfunc (a *AlterTable) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ALTER TABLE \")\n\tformatter.WriteExpr(a.TableIdentifier)\n\tif a.OnCluster != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(a.OnCluster)\n\t}\n\tfor i, expr := range a.AlterExprs {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(expr)\n\t\tif i != len(a.AlterExprs)-1 {\n\t\t\tformatter.WriteString(\",\")\n\t\t}\n\t}\n}\n\nfunc (a *AlterTableAddColumn) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ADD COLUMN \")\n\tif a.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(a.Column)\n\tif a.After != nil {\n\t\tformatter.WriteString(\" AFTER \")\n\t\tformatter.WriteExpr(a.After)\n\t}\n\tif a.Settings != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(a.Settings)\n\t}\n}\n\nfunc (a *AlterTableAddIndex) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ADD \")\n\tif a.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(a.Index)\n\tif a.After != nil {\n\t\tformatter.WriteString(\" AFTER \")\n\t\tformatter.WriteExpr(a.After)\n\t}\n}\n\nfunc (a *AlterTableAddProjection) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ADD PROJECTION \")\n\tif a.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(a.TableProjection)\n\tif a.After != nil {\n\t\tformatter.WriteString(\" AFTER \")\n\t\tformatter.WriteExpr(a.After)\n\t}\n}\n\nfunc (a *AlterTableAttachPartition) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ATTACH \")\n\tformatter.WriteExpr(a.Partition)\n\tif a.From != nil {\n\t\tformatter.WriteString(\" FROM \")\n\t\tformatter.WriteExpr(a.From)\n\t}\n}\n\nfunc (a *AlterTableClearColumn) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CLEAR COLUMN \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.ColumnName)\n\tif a.PartitionExpr != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"IN \")\n\t\tformatter.WriteExpr(a.PartitionExpr)\n\t}\n\n}\n\nfunc (a *AlterTableClearIndex) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CLEAR INDEX \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.IndexName)\n\tif a.PartitionExpr != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"IN \")\n\t\tformatter.WriteExpr(a.PartitionExpr)\n\t}\n\n}\n\nfunc (a *AlterTableClearProjection) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CLEAR PROJECTION \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.ProjectionName)\n\tif a.PartitionExpr != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"IN \")\n\t\tformatter.WriteExpr(a.PartitionExpr)\n\t}\n\n}\n\nfunc (a *AlterTableDelete) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DELETE\")\n\tformatter.Break()\n\tformatter.WriteString(\"WHERE \")\n\tformatter.WriteExpr(a.WhereClause)\n}\n\nfunc (a *AlterTableDetachPartition) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DETACH \")\n\tformatter.WriteExpr(a.Partition)\n\tif a.Settings != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(a.Settings)\n\t}\n}\n\nfunc (a *AlterTableDropColumn) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP COLUMN \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.ColumnName)\n}\n\nfunc (a *AlterTableDropIndex) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP INDEX \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.IndexName)\n}\n\nfunc (a *AlterTableDropPartition) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP \")\n\tif a.HasDetached {\n\t\tformatter.WriteString(\"DETACHED \")\n\t}\n\tformatter.WriteExpr(a.Partition)\n\tif a.Settings != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(a.Settings)\n\t}\n}\n\nfunc (a *AlterTableDropProjection) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP PROJECTION \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.ProjectionName)\n}\n\nfunc (a *AlterTableFreezePartition) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"FREEZE\")\n\tif a.Partition != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(a.Partition)\n\t}\n}\n\nfunc (a *AlterTableMaterializeIndex) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"MATERIALIZE INDEX\")\n\n\tif a.IfExists {\n\t\tformatter.WriteString(\" IF EXISTS\")\n\t}\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(a.IndexName)\n\tif a.Partition != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"IN \")\n\t\tformatter.WriteExpr(a.Partition)\n\t}\n}\n\nfunc (a *AlterTableMaterializeProjection) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"MATERIALIZE PROJECTION\")\n\n\tif a.IfExists {\n\t\tformatter.WriteString(\" IF EXISTS\")\n\t}\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(a.ProjectionName)\n\tif a.Partition != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"IN \")\n\t\tformatter.WriteExpr(a.Partition)\n\t}\n}\n\nfunc (a *AlterTableModifyColumn) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"MODIFY COLUMN \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.Column)\n\tif a.RemovePropertyType != nil {\n\t\tformatter.WriteExpr(a.RemovePropertyType)\n\t}\n}\n\nfunc (a *AlterTableModifyQuery) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"MODIFY QUERY\")\n\tformatter.Indent()\n\tformatter.Break()\n\tformatter.WriteExpr(a.SelectExpr)\n\tformatter.Dedent()\n}\n\nfunc (a *AlterTableModifySetting) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"MODIFY SETTING\")\n\tformatter.Indent()\n\tfor i, setting := range a.Settings {\n\t\tif i == 0 {\n\t\t\tformatter.Break()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(setting)\n\t}\n\tformatter.Dedent()\n}\n\nfunc (a *AlterTableModifyTTL) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"MODIFY \")\n\tformatter.WriteExpr(a.TTL)\n}\n\nfunc (a *AlterTableRemoveTTL) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"REMOVE TTL\")\n}\n\nfunc (a *AlterTableRenameColumn) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"RENAME COLUMN \")\n\tif a.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(a.OldColumnName)\n\tformatter.WriteString(\" TO \")\n\tformatter.WriteExpr(a.NewColumnName)\n}\n\nfunc (a *AlterTableReplacePartition) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"REPLACE \")\n\tformatter.WriteExpr(a.Partition)\n\tformatter.WriteString(\" FROM \")\n\tformatter.WriteExpr(a.Table)\n}\n\nfunc (a *AlterTableResetSetting) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"RESET SETTING\")\n\tformatter.Indent()\n\tfor i, setting := range a.Settings {\n\t\tif i == 0 {\n\t\t\tformatter.Break()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(setting)\n\t}\n\tformatter.Dedent()\n}\n\nfunc (a *AlterTableUpdate) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"UPDATE\")\n\tformatter.Indent()\n\tfor i, assignment := range a.Assignments {\n\t\tif i == 0 {\n\t\t\tformatter.Break()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(assignment)\n\t}\n\tformatter.Dedent()\n\tif a.InPartition != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"IN \")\n\t\tformatter.WriteExpr(a.InPartition)\n\t}\n\tformatter.Break()\n\tformatter.WriteString(\"WHERE \")\n\tformatter.WriteExpr(a.WhereClause)\n}\n\nfunc (a *ArrayParamList) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"[\")\n\tfor i, item := range a.Items.Items {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(item)\n\t}\n\tformatter.WriteString(\"]\")\n}\n\nfunc (v *AssignmentValues) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\tfor i, value := range v.Values {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(value)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (a *AuthenticationClause) FormatSQL(formatter *Formatter) {\n\tif a.NotIdentified {\n\t\tformatter.WriteString(\"NOT IDENTIFIED\")\n\t\treturn\n\t}\n\tformatter.WriteString(\"IDENTIFIED\")\n\tif a.AuthType != \"\" {\n\t\tformatter.WriteString(\" WITH \")\n\t\tformatter.WriteString(a.AuthType)\n\t}\n\tif a.AuthValue != nil {\n\t\tformatter.WriteString(\" BY \")\n\t\tformatter.WriteExpr(a.AuthValue)\n\t}\n\tif a.LdapServer != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"WITH ldap SERVER \")\n\t\tformatter.WriteExpr(a.LdapServer)\n\t}\n\tif a.IsKerberos {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"WITH kerberos\")\n\t\tif a.KerberosRealm != nil && a.KerberosRealm.Literal != \"\" {\n\t\t\tformatter.WriteString(\" REALM \")\n\t\t\tformatter.WriteExpr(a.KerberosRealm)\n\t\t}\n\t}\n}\n\nfunc (f *BetweenClause) FormatSQL(formatter *Formatter) {\n\tif f.Expr != nil {\n\t\tformatter.WriteExpr(f.Expr)\n\t\tformatter.WriteString(\" BETWEEN \")\n\t} else {\n\t\tformatter.WriteString(\"BETWEEN \")\n\t}\n\tformatter.WriteExpr(f.Between)\n\tformatter.WriteString(\" AND \")\n\tformatter.WriteExpr(f.And)\n}\n\nfunc (b *BoolLiteral) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(b.Literal)\n}\n\nfunc (c *CTEStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Expr)\n\tformatter.WriteString(\" AS \")\n\tif _, isSelect := c.Alias.(*SelectQuery); isSelect {\n\t\tformatter.WriteByte('(')\n\t\tformatter.WriteExpr(c.Alias)\n\t\tformatter.WriteByte(')')\n\t} else {\n\t\tformatter.WriteExpr(c.Alias)\n\t}\n}\n\nfunc (c *CaseExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CASE\")\n\tif c.Expr != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.Expr)\n\t}\n\tformatter.Indent()\n\tfor _, when := range c.Whens {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(when)\n\t}\n\tif c.Else != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"ELSE \")\n\t\tformatter.WriteExpr(c.Else)\n\t}\n\tformatter.Dedent()\n\tformatter.Break()\n\tformatter.WriteString(\"END\")\n}\n\nfunc (c *CastExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CAST(\")\n\tformatter.WriteExpr(c.Expr)\n\tif c.Separator == \",\" {\n\t\tformatter.WriteString(\", \")\n\t} else {\n\t\tformatter.WriteString(\" AS \")\n\t}\n\tformatter.WriteExpr(c.AsType)\n\tformatter.WriteByte(')')\n}\n\nfunc (c *CheckStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CHECK TABLE \")\n\tformatter.WriteExpr(c.Table)\n\tif c.Partition != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.Partition)\n\t}\n}\n\nfunc (o *ClusterClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ON CLUSTER \")\n\tformatter.WriteExpr(o.Expr)\n}\n\nfunc (c *ColumnArgList) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\tfor i, item := range c.Items {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(item)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (c *ColumnDef) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Name)\n\tif c.Type != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.Type)\n\t}\n\tif c.NotNull != nil {\n\t\tformatter.WriteString(\" NOT NULL\")\n\t} else if c.Nullable != nil {\n\t\tformatter.WriteString(\" NULL\")\n\t}\n\tif c.DefaultExpr != nil {\n\t\tformatter.WriteString(\" DEFAULT \")\n\t\tformatter.WriteExpr(c.DefaultExpr)\n\t}\n\tif c.MaterializedExpr != nil {\n\t\tformatter.WriteString(\" MATERIALIZED \")\n\t\tformatter.WriteExpr(c.MaterializedExpr)\n\t}\n\tif c.AliasExpr != nil {\n\t\tformatter.WriteString(\" ALIAS \")\n\t\tformatter.WriteExpr(c.AliasExpr)\n\t}\n\tif c.Codec != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.Codec)\n\t}\n\tif c.TTL != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.TTL)\n\t}\n\tif c.Comment != nil {\n\t\tformatter.WriteString(\" COMMENT \")\n\t\tformatter.WriteExpr(c.Comment)\n\t}\n}\n\nfunc (c *ColumnExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Expr)\n\tif c.Alias != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(c.Alias)\n\t}\n}\n\nfunc (c *ColumnExprList) FormatSQL(formatter *Formatter) {\n\tif c.HasDistinct {\n\t\tformatter.WriteString(\"DISTINCT \")\n\t}\n\tfor i, item := range c.Items {\n\t\tformatter.WriteExpr(item)\n\t\tif i != len(c.Items)-1 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t}\n}\n\nfunc (c *ColumnNamesExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\tfor i, column := range c.ColumnNames {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tcolumnExpr := column\n\t\tformatter.WriteExpr(&columnExpr)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (c *ColumnTypeExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Name)\n}\n\nfunc (c *ComplexType) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Name)\n\tformatter.WriteByte('(')\n\tfor i, param := range c.Params {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(param)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (c *CompressionCodec) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CODEC(\")\n\tif c.Type != nil {\n\t\tformatter.WriteExpr(c.Type)\n\t\tif c.TypeLevel != nil {\n\t\t\tformatter.WriteByte('(')\n\t\t\tformatter.WriteExpr(c.TypeLevel)\n\t\t\tformatter.WriteByte(')')\n\t\t}\n\t\tformatter.WriteByte(',')\n\t\tformatter.WriteByte(whitespace)\n\t}\n\tif c.Name != nil {\n\t\tformatter.WriteExpr(c.Name)\n\t\tif c.Level != nil {\n\t\t\tformatter.WriteByte('(')\n\t\t\tformatter.WriteExpr(c.Level)\n\t\t\tformatter.WriteByte(')')\n\t\t}\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (c *ConstraintClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Constraint)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(c.Expr)\n}\n\nfunc (c *CreateDatabase) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE DATABASE \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\tif c.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\tif c.Engine != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Engine)\n\t}\n\tif c.Comment != nil {\n\t\tformatter.WriteString(\" COMMENT \")\n\t\tformatter.WriteExpr(c.Comment)\n\t}\n}\n\nfunc (c *CreateDictionary) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE \")\n\tif c.OrReplace {\n\t\tformatter.WriteString(\"OR REPLACE \")\n\t}\n\tformatter.WriteString(\"DICTIONARY \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\n\tif c.UUID != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.UUID)\n\t}\n\n\tif c.OnCluster != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\n\tif c.Schema != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Schema)\n\t}\n\n\tif c.Engine != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Engine)\n\t}\n\n\tif c.Comment != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"COMMENT \")\n\t\tformatter.WriteExpr(c.Comment)\n\t}\n\n}\n\nfunc (c *CreateFunction) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE\")\n\tif c.OrReplace {\n\t\tformatter.WriteString(\" OR REPLACE\")\n\t}\n\tformatter.WriteString(\" FUNCTION \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.FunctionName)\n\tif c.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\tformatter.WriteString(\" AS \")\n\tformatter.WriteExpr(c.Params)\n\tformatter.WriteString(\" -> \")\n\tformatter.WriteExpr(c.Expr)\n}\n\nfunc (c *CreateLiveView) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE LIVE VIEW \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\n\tif c.OnCluster != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\n\tif c.WithTimeout != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.WithTimeout)\n\t}\n\n\tif c.Destination != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Destination)\n\t}\n\n\tif c.TableSchema != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.TableSchema)\n\t}\n\n\tif c.SubQuery != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"AS \")\n\t\tformatter.WriteExpr(c.SubQuery)\n\t}\n}\n\nfunc (c *CreateMaterializedView) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE MATERIALIZED VIEW \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\tif c.OnCluster != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\tif c.Refresh != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Refresh)\n\t}\n\tif c.RandomizeFor != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"RANDOMIZE FOR \")\n\t\tformatter.WriteExpr(c.RandomizeFor)\n\t}\n\tif c.DependsOn != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"DEPENDS ON \")\n\t\tfor i, dep := range c.DependsOn {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\tformatter.WriteExpr(dep)\n\t\t}\n\t}\n\tif c.Settings != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Settings)\n\t}\n\tif c.HasAppend {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"APPEND\")\n\t}\n\tif c.Engine != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Engine)\n\t}\n\tif c.Destination != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Destination)\n\t\tif c.Destination.TableSchema != nil {\n\t\t\tformatter.Break()\n\t\t\tformatter.WriteExpr(c.Destination.TableSchema)\n\t\t}\n\t}\n\tif c.HasEmpty {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"EMPTY\")\n\t}\n\tif c.Definer != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"DEFINER = \")\n\t\tformatter.WriteExpr(c.Definer)\n\t}\n\tif c.SQLSecurity != \"\" {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"SQL SECURITY \")\n\t\tformatter.WriteString(c.SQLSecurity)\n\t}\n\tif c.Populate {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"POPULATE\")\n\t}\n\tif c.SubQuery != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"AS\")\n\t\tformatter.Indent()\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.SubQuery)\n\t\tformatter.Dedent()\n\t}\n\tif c.Comment != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"COMMENT \")\n\t\tformatter.WriteExpr(c.Comment)\n\t}\n}\n\nfunc (c *CreateNamedCollection) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE NAMED COLLECTION \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\tif c.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\tformatter.WriteString(\" AS \")\n\tfor i, param := range c.Params {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(param)\n\t}\n}\n\nfunc (c *CreateRole) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE ROLE \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tif c.OrReplace {\n\t\tformatter.WriteString(\"OR REPLACE \")\n\t}\n\tfor i, roleName := range c.RoleNames {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(roleName)\n\t}\n\tif c.AccessStorageType != nil {\n\t\tformatter.WriteString(\" IN \")\n\t\tformatter.WriteExpr(c.AccessStorageType)\n\t}\n\tif len(c.Settings) > 0 {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"SETTINGS\")\n\t\tformatter.Indent()\n\t\tfor i, setting := range c.Settings {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\",\")\n\t\t\t}\n\t\t\tformatter.Break()\n\t\t\tformatter.WriteExpr(setting)\n\t\t}\n\t\tformatter.Dedent()\n\t}\n}\n\nfunc (c *CreateTable) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE\")\n\tif c.OrReplace {\n\t\tformatter.WriteString(\" OR REPLACE\")\n\t}\n\tif c.HasTemporary {\n\t\tformatter.WriteString(\" TEMPORARY\")\n\t}\n\tformatter.WriteString(\" TABLE \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\tif c.UUID != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.UUID)\n\t}\n\tif c.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\n\tif c.TableSchema != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.TableSchema)\n\t}\n\tif c.Engine != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Engine)\n\t}\n\tif c.SubQuery != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"AS \")\n\t\tformatter.WriteExpr(c.SubQuery)\n\t}\n\tif c.TableFunction != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"AS \")\n\t\tformatter.WriteExpr(c.TableFunction)\n\t}\n\tif c.Comment != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"COMMENT \")\n\t\tformatter.WriteExpr(c.Comment)\n\t}\n}\n\nfunc (c *CreateUser) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE USER \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tif c.OrReplace {\n\t\tformatter.WriteString(\"OR REPLACE \")\n\t}\n\tfor i, userName := range c.UserNames {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(userName)\n\t}\n\tif c.Authentication != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Authentication)\n\t}\n\tif c.ValidUntil != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"VALID UNTIL \")\n\t\tformatter.WriteExpr(c.ValidUntil)\n\t}\n\tif len(c.Hosts) > 0 {\n\t\tformatter.Break()\n\t\tfor i, host := range c.Hosts {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\tformatter.WriteExpr(host)\n\t\t}\n\t}\n\tif c.DefaultRole != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.DefaultRole)\n\t}\n\tif c.DefaultDatabase != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"DEFAULT DATABASE \")\n\t\tformatter.WriteExpr(c.DefaultDatabase)\n\t} else if c.DefaultDbNone {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"DEFAULT DATABASE NONE\")\n\t}\n\tif c.Grantees != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(c.Grantees)\n\t}\n\tif len(c.Settings) > 0 {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"SETTINGS\")\n\t\tformatter.Indent()\n\t\tfor i, setting := range c.Settings {\n\t\t\tformatter.Break()\n\t\t\tformatter.WriteExpr(setting)\n\t\t\tif i < len(c.Settings)-1 {\n\t\t\t\tformatter.WriteString(\",\")\n\t\t\t}\n\t\t}\n\t\tformatter.Dedent()\n\t}\n}\n\nfunc (c *CreateView) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CREATE\")\n\tif c.OrReplace {\n\t\tformatter.WriteString(\" OR REPLACE\")\n\t}\n\tformatter.WriteString(\" VIEW \")\n\tif c.IfNotExists {\n\t\tformatter.WriteString(\"IF NOT EXISTS \")\n\t}\n\tformatter.WriteExpr(c.Name)\n\tif c.UUID != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.UUID)\n\t}\n\n\tif c.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.OnCluster)\n\t}\n\n\tif c.TableSchema != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(c.TableSchema)\n\t}\n\n\tif c.Comment != nil {\n\t\tformatter.WriteString(\" COMMENT \")\n\t\tformatter.WriteExpr(c.Comment)\n\t}\n\n\tif c.SubQuery != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(c.SubQuery)\n\t}\n}\n\nfunc (d *DeduplicateClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\" DEDUPLICATE\")\n\tif d.By != nil {\n\t\tformatter.WriteString(\" BY \")\n\t\tformatter.WriteExpr(d.By)\n\t}\n\tif d.Except != nil {\n\t\tformatter.WriteString(\" EXCEPT \")\n\t\tformatter.WriteExpr(d.Except)\n\t}\n}\n\nfunc (d *DefaultRoleClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DEFAULT ROLE \")\n\tif d.None {\n\t\tformatter.WriteString(\"NONE\")\n\t} else {\n\t\tfor i, role := range d.Roles {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\tformatter.WriteExpr(role)\n\t\t}\n\t}\n}\n\nfunc (d *DeleteClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DELETE FROM \")\n\tformatter.WriteExpr(d.Table)\n\tif d.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(d.OnCluster)\n\t}\n\tif d.WhereExpr != nil {\n\t\tformatter.WriteString(\" WHERE \")\n\t\tformatter.WriteExpr(d.WhereExpr)\n\t}\n}\n\nfunc (d *DescribeStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DESCRIBE \")\n\tif d.DescribeType != \"\" {\n\t\tformatter.WriteString(d.DescribeType)\n\t\tformatter.WriteByte(whitespace)\n\t}\n\tformatter.WriteExpr(d.Target)\n}\n\nfunc (d *DestinationClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"TO \")\n\tformatter.WriteExpr(d.TableIdentifier)\n}\n\nfunc (d *DictionaryArgExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(d.Name)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(d.Value)\n}\n\nfunc (d *DictionaryAttribute) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(d.Name)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(d.Type)\n\n\tif d.Default != nil {\n\t\tformatter.WriteString(\" DEFAULT \")\n\t\tformatter.WriteExpr(d.Default)\n\t}\n\n\tif d.Expression != nil {\n\t\tformatter.WriteString(\" EXPRESSION \")\n\t\tformatter.WriteExpr(d.Expression)\n\t}\n\n\tif d.Hierarchical {\n\t\tformatter.WriteString(\" HIERARCHICAL\")\n\t}\n\n\tif d.Injective {\n\t\tformatter.WriteString(\" INJECTIVE\")\n\t}\n\n\tif d.IsObjectId {\n\t\tformatter.WriteString(\" IS_OBJECT_ID\")\n\t}\n\n}\n\nfunc (d *DictionaryEngineClause) FormatSQL(formatter *Formatter) {\n\tneedsBreak := false\n\tbreakAndWrite := func(expr Expr) {\n\t\tif needsBreak {\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(expr)\n\t\tneedsBreak = true\n\t}\n\n\tif d.PrimaryKey != nil {\n\t\tbreakAndWrite(d.PrimaryKey)\n\t}\n\tif d.Source != nil {\n\t\tbreakAndWrite(d.Source)\n\t}\n\tif d.Lifetime != nil {\n\t\tbreakAndWrite(d.Lifetime)\n\t}\n\tif d.Layout != nil {\n\t\tbreakAndWrite(d.Layout)\n\t}\n\tif d.Range != nil {\n\t\tbreakAndWrite(d.Range)\n\t}\n\tif d.Settings != nil {\n\t\tif needsBreak {\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteString(\"SETTINGS(\")\n\t\tfor i, item := range d.Settings.Items {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\tformatter.WriteExpr(item)\n\t\t}\n\t\tformatter.WriteString(\")\")\n\t}\n}\n\nfunc (d *DictionaryLayoutClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"LAYOUT(\")\n\tformatter.WriteExpr(d.Layout)\n\tformatter.WriteString(\"(\")\n\tfor i, arg := range d.Args {\n\t\tif i > 0 {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteExpr(arg)\n\t}\n\tformatter.WriteString(\"))\")\n}\n\nfunc (d *DictionaryLifetimeClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"LIFETIME(\")\n\tif d.Value != nil {\n\t\tformatter.WriteExpr(d.Value)\n\t} else if d.Min != nil && d.Max != nil {\n\t\tformatter.WriteString(\"MIN \")\n\t\tformatter.WriteExpr(d.Min)\n\t\tformatter.WriteString(\" MAX \")\n\t\tformatter.WriteExpr(d.Max)\n\t}\n\tformatter.WriteString(\")\")\n}\n\nfunc (d *DictionaryPrimaryKeyClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"PRIMARY KEY \")\n\tformatter.WriteExpr(d.Keys)\n}\n\nfunc (d *DictionaryRangeClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"RANGE(\")\n\tformatter.WriteString(\"MIN \")\n\tif d.Min != nil {\n\t\tformatter.WriteExpr(d.Min)\n\t}\n\tif d.Max != nil {\n\t\tformatter.WriteString(\" MAX \")\n\t\tformatter.WriteExpr(d.Max)\n\t}\n\tformatter.WriteString(\")\")\n}\n\nfunc (d *DictionarySchemaClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\tformatter.Indent()\n\tfor i, attr := range d.Attributes {\n\t\tif i == 0 {\n\t\t\tformatter.NewLine()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(attr)\n\t}\n\tformatter.Dedent()\n\tformatter.NewLine()\n\tformatter.WriteByte(')')\n}\n\nfunc (d *DictionarySourceClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SOURCE(\")\n\tformatter.WriteExpr(d.Source)\n\tformatter.WriteString(\"(\")\n\tfor i, arg := range d.Args {\n\t\tif i > 0 {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteExpr(arg)\n\t}\n\tformatter.WriteString(\"))\")\n}\n\nfunc (s *DistinctOn) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ON (\")\n\tfor i, ident := range s.Idents {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(ident)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (d *DropDatabase) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP DATABASE \")\n\tif d.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(d.Name)\n\tif d.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(d.OnCluster)\n\t}\n}\n\nfunc (d *DropStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP \")\n\tif d.IsTemporary {\n\t\tformatter.WriteString(\"TEMPORARY \")\n\t}\n\tformatter.WriteString(d.DropTarget + \" \")\n\tif d.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(d.Name)\n\tif d.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(d.OnCluster)\n\t}\n\tif len(d.Modifier) != 0 {\n\t\tformatter.WriteString(\" \" + d.Modifier)\n\t}\n}\n\nfunc (d *DropUserOrRole) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP \" + d.Target + \" \")\n\tif d.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tfor i, name := range d.Names {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(name)\n\t}\n\tif len(d.Modifier) != 0 {\n\t\tformatter.WriteString(\" \" + d.Modifier)\n\t}\n\tif d.From != nil {\n\t\tformatter.WriteString(\" FROM \")\n\t\tformatter.WriteExpr(d.From)\n\t}\n}\n\nfunc (e *EngineExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ENGINE = \")\n\tformatter.WriteString(e.Name)\n\tif e.Params != nil {\n\t\tformatter.WriteExpr(e.Params)\n\t}\n\tif e.OrderBy != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(e.OrderBy)\n\t}\n\tif e.PartitionBy != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(e.PartitionBy)\n\t}\n\tif e.PrimaryKey != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(e.PrimaryKey)\n\t}\n\tif e.SampleBy != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(e.SampleBy)\n\t}\n\tif e.TTL != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(e.TTL)\n\t}\n\tif e.Settings != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(e.Settings)\n\t}\n}\n\nfunc (e *EnumType) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(e.Name)\n\tformatter.WriteByte('(')\n\tfor i, enum := range e.Values {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tenumExpr := enum\n\t\tformatter.WriteExpr(&enumExpr)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (e *EnumValue) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(e.Name)\n\tformatter.WriteByte('=')\n\tformatter.WriteExpr(e.Value)\n}\n\nfunc (e *ExplainStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"EXPLAIN \")\n\tformatter.WriteString(e.Type)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(e.Statement)\n}\n\nfunc (e *ExtractExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"EXTRACT(\")\n\tfor i, param := range e.Parameters {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(param)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (f *Fill) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"WITH FILL\")\n\tif f.From != nil {\n\t\tformatter.WriteString(\" FROM \")\n\t\tformatter.WriteExpr(f.From)\n\t}\n\tif f.To != nil {\n\t\tformatter.WriteString(\" TO \")\n\t\tformatter.WriteExpr(f.To)\n\t}\n\tif f.Step != nil {\n\t\tformatter.WriteString(\" STEP \")\n\t\tformatter.WriteExpr(f.Step)\n\t}\n\tif f.Staleness != nil {\n\t\tformatter.WriteString(\" STALENESS \")\n\t\tformatter.WriteExpr(f.Staleness)\n\t}\n}\n\nfunc (f *FormatClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"FORMAT \")\n\tformatter.WriteExpr(f.Format)\n}\n\nfunc (f *FromClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"FROM\")\n\tformatter.Indent()\n\tformatter.Break()\n\tformatter.WriteExpr(f.Expr)\n\tformatter.Dedent()\n}\n\nfunc (f *FunctionExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(f.Name)\n\tformatter.WriteExpr(f.Params)\n}\n\nfunc (g *GlobalInOperation) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"GLOBAL \")\n\tformatter.WriteExpr(g.Expr)\n}\n\nfunc (g *GrantPrivilegeStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"GRANT \")\n\tif g.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(g.OnCluster)\n\t}\n\tfor i, privilege := range g.Privileges {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(privilege)\n\t}\n\tformatter.WriteString(\" ON \")\n\tformatter.WriteExpr(g.On)\n\tformatter.WriteString(\" TO \")\n\tfor i, role := range g.To {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(role)\n\t}\n\tfor _, option := range g.WithOptions {\n\t\tformatter.WriteString(\" WITH \" + option + \" OPTION\")\n\t}\n\n}\n\nfunc (g *GranteesClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"GRANTEES \")\n\tif g.Any {\n\t\tformatter.WriteString(\"ANY\")\n\t} else if g.None {\n\t\tformatter.WriteString(\"NONE\")\n\t} else {\n\t\tfor i, grantee := range g.Grantees {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\tformatter.WriteExpr(grantee)\n\t\t}\n\t}\n\tif len(g.ExceptUsers) > 0 {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"EXCEPT \")\n\t\tfor i, except := range g.ExceptUsers {\n\t\t\tif i > 0 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\tformatter.WriteExpr(except)\n\t\t}\n\t}\n}\n\nfunc (g *GroupByClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"GROUP BY\")\n\n\tformatter.Indent()\n\tdefer formatter.Dedent()\n\tif g.AggregateType != \"\" {\n\t\tformatter.Break()\n\t\tformatter.WriteString(g.AggregateType)\n\t}\n\tif g.Expr != nil {\n\t\tif g.AggregateType == \"\" {\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(g.Expr)\n\t}\n\tif g.WithCube {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"WITH CUBE\")\n\t}\n\tif g.WithRollup {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"WITH ROLLUP\")\n\t}\n\tif g.WithTotals {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"WITH TOTALS\")\n\t}\n}\n\nfunc (h *HavingClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"HAVING \")\n\tformatter.WriteExpr(h.Expr)\n}\n\nfunc (h *HostClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"HOST \")\n\tformatter.WriteString(h.HostType)\n\tif h.HostValue != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(h.HostValue)\n\t}\n}\n\nfunc (i *Ident) FormatSQL(formatter *Formatter) {\n\tswitch i.QuoteType {\n\tcase BackTicks:\n\t\tformatter.WriteByte('`')\n\t\tformatter.WriteString(i.Name)\n\t\tformatter.WriteByte('`')\n\tcase DoubleQuote:\n\t\tformatter.WriteByte('\"')\n\t\tformatter.WriteString(i.Name)\n\t\tformatter.WriteByte('\"')\n\tcase SingleQuote:\n\t\tformatter.WriteByte('\\'')\n\t\tformatter.WriteString(i.Name)\n\t\tformatter.WriteByte('\\'')\n\tdefault:\n\t\tformatter.WriteString(i.Name)\n\t}\n}\n\nfunc (i *IndexOperation) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(i.Object)\n\tformatter.WriteString(string(i.Operation))\n\tformatter.WriteExpr(i.Index)\n}\n\nfunc (i *InsertStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"INSERT INTO \")\n\tif i.HasTableKeyword {\n\t\tformatter.WriteString(\"TABLE \")\n\t}\n\tformatter.WriteExpr(i.Table)\n\tif i.ColumnNames != nil {\n\t\tformatter.Break()\n\t\tformatter.Indent()\n\t\tformatter.WriteExpr(i.ColumnNames)\n\t\tformatter.Dedent()\n\t}\n\tif i.Format != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(i.Format)\n\t}\n\n\tif i.SelectExpr != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(i.SelectExpr)\n\t} else if len(i.Values) > 0 {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"VALUES\")\n\t\tformatter.Indent()\n\t\tfor j, value := range i.Values {\n\t\t\tformatter.Break()\n\t\t\tformatter.WriteExpr(value)\n\t\t\tif j != len(i.Values)-1 {\n\t\t\t\tformatter.WriteByte(',')\n\t\t\t}\n\t\t}\n\t\tformatter.Dedent()\n\t}\n}\n\nfunc (i *InterpolateClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"INTERPOLATE\")\n\tif len(i.Items) > 0 {\n\t\tformatter.WriteString(\" (\")\n\t\tfor idx, item := range i.Items {\n\t\t\tformatter.WriteExpr(item)\n\t\t\tif idx != len(i.Items)-1 {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t}\n\t\tformatter.WriteByte(')')\n\t}\n}\n\nfunc (i *InterpolateItem) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(i.Column)\n\tif i.Expr != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(i.Expr)\n\t}\n}\n\nfunc (i *IntervalExpr) FormatSQL(formatter *Formatter) {\n\tif i.IntervalPos != 0 {\n\t\tformatter.WriteString(\"INTERVAL \")\n\t}\n\tformatter.WriteExpr(i.Expr)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(i.Unit)\n}\n\nfunc (i *IntervalFrom) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(i.Interval)\n\tformatter.WriteString(\" FROM \")\n\tformatter.WriteExpr(i.FromExpr)\n}\n\nfunc (n *IsNotNullExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(n.Expr)\n\tformatter.WriteString(\" IS NOT NULL\")\n}\n\nfunc (n *IsNullExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(n.Expr)\n\tformatter.WriteString(\" IS NULL\")\n}\n\nfunc (j *JSONPath) FormatSQL(formatter *Formatter) {\n\tfor i, ident := range j.Idents {\n\t\tif i > 0 {\n\t\t\tformatter.WriteByte('.')\n\t\t}\n\t\tformatter.WriteExpr(ident)\n\t}\n}\n\nfunc (j *JSONOption) FormatSQL(formatter *Formatter) {\n\twroteAny := false\n\tif j.SkipPath != nil {\n\t\tformatter.WriteString(\"SKIP \")\n\t\tj.SkipPath.FormatSQL(formatter)\n\t\twroteAny = true\n\t}\n\tif j.SkipRegex != nil {\n\t\tformatter.WriteString(\" SKIP REGEXP \")\n\t\tformatter.WriteExpr(j.SkipRegex)\n\t\twroteAny = true\n\t}\n\tif j.MaxDynamicPaths != nil {\n\t\tformatter.WriteString(\"max_dynamic_paths\")\n\t\tformatter.WriteByte('=')\n\t\tformatter.WriteExpr(j.MaxDynamicPaths)\n\t\twroteAny = true\n\t}\n\tif j.MaxDynamicTypes != nil {\n\t\tformatter.WriteString(\"max_dynamic_types\")\n\t\tformatter.WriteByte('=')\n\t\tformatter.WriteExpr(j.MaxDynamicTypes)\n\t\twroteAny = true\n\t}\n\tif j.Column != nil && j.Column.Path != nil && j.Column.Type != nil {\n\t\t// Add a leading space if there is already content.\n\t\tif wroteAny {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tj.Column.Path.FormatSQL(formatter)\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(j.Column.Type)\n\t}\n}\n\nfunc (j *JSONOptions) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\t// Ensure stable, readable ordering:\n\t// 1) numeric options (max_dynamic_*), 2) type-hint items, 3) skip options (SKIP, SKIP REGEXP)\n\t// Preserve original relative order within each group.\n\tnumericOptionItems := make([]*JSONOption, 0, len(j.Items))\n\tcolumnItems := make([]*JSONOption, 0, len(j.Items))\n\tskipOptionItems := make([]*JSONOption, 0, len(j.Items))\n\tfor _, item := range j.Items {\n\t\tif item.MaxDynamicPaths != nil || item.MaxDynamicTypes != nil {\n\t\t\tnumericOptionItems = append(numericOptionItems, item)\n\t\t\tcontinue\n\t\t}\n\t\tif item.Column != nil {\n\t\t\tcolumnItems = append(columnItems, item)\n\t\t\tcontinue\n\t\t}\n\t\tif item.SkipPath != nil || item.SkipRegex != nil {\n\t\t\tskipOptionItems = append(skipOptionItems, item)\n\t\t\tcontinue\n\t\t}\n\t\t// Fallback: treat as numeric option to avoid dropping unknown future fields.\n\t\tnumericOptionItems = append(numericOptionItems, item)\n\t}\n\n\twroteItem := false\n\twriteItems := func(items []*JSONOption) {\n\t\tfor _, item := range items {\n\t\t\tif wroteItem {\n\t\t\t\tformatter.WriteString(\", \")\n\t\t\t}\n\t\t\titem.FormatSQL(formatter)\n\t\t\twroteItem = true\n\t\t}\n\t}\n\n\twriteItems(numericOptionItems)\n\twriteItems(columnItems)\n\twriteItems(skipOptionItems)\n\tformatter.WriteByte(')')\n}\n\nfunc (j *JSONType) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(j.Name)\n\tif j.Options != nil {\n\t\tj.Options.FormatSQL(formatter)\n\t}\n}\n\nfunc (j *JoinConstraintClause) FormatSQL(formatter *Formatter) {\n\tif j.On != nil {\n\t\tformatter.WriteString(\"ON \")\n\t\tformatter.WriteExpr(j.On)\n\t} else {\n\t\tformatter.WriteString(\"USING \")\n\t\tformatter.WriteExpr(j.Using)\n\t}\n}\n\nfunc (j *JoinExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(j.Left)\n\tif j.Right != nil {\n\t\twriteJoinSQL(formatter, j.Right)\n\t}\n}\n\nfunc writeJoinSQL(formatter *Formatter, expr Expr) {\n\tjoinExpr, ok := expr.(*JoinExpr)\n\tif !ok {\n\t\tformatter.WriteByte(',')\n\t\tformatter.WriteExpr(expr)\n\t\treturn\n\t}\n\n\tif len(joinExpr.Modifiers) == 0 {\n\t\tformatter.WriteByte(',')\n\t\tformatter.WriteExpr(joinExpr.Left)\n\t} else {\n\t\tformatter.Break()\n\t\tformatter.WriteString(strings.Join(joinExpr.Modifiers, \" \"))\n\t\tformatter.Indent()\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(joinExpr.Left)\n\t\tif joinExpr.Constraints != nil {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t\tformatter.WriteExpr(joinExpr.Constraints)\n\t\t}\n\t\tformatter.Dedent()\n\t}\n\tif joinExpr.Right != nil {\n\t\twriteJoinSQL(formatter, joinExpr.Right)\n\t}\n}\n\nfunc (j *JoinTableExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(j.Table)\n\tif j.SampleRatio != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(j.SampleRatio)\n\t}\n\tif j.HasFinal {\n\t\tformatter.WriteString(\" FINAL\")\n\t}\n}\n\nfunc (l *LimitByClause) FormatSQL(formatter *Formatter) {\n\tif l.Limit != nil {\n\t\tformatter.WriteExpr(l.Limit)\n\t}\n\tif l.ByExpr != nil {\n\t\tformatter.WriteString(\" BY \")\n\t\tformatter.WriteExpr(l.ByExpr)\n\t}\n}\n\nfunc (l *LimitClause) FormatSQL(formatter *Formatter) {\n\tif l.Limit != nil {\n\t\tformatter.WriteString(\"LIMIT \")\n\t\tformatter.WriteExpr(l.Limit)\n\t\tif l.Offset != nil {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t}\n\tif l.Offset != nil {\n\t\tformatter.WriteString(\"OFFSET \")\n\t\tformatter.WriteExpr(l.Offset)\n\t}\n}\n\nfunc (m *MapLiteral) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"{\")\n\n\tfor i, value := range m.KeyValues {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tkey := value.Key\n\t\tformatter.WriteExpr(&key)\n\t\tformatter.WriteString(\": \")\n\t\tformatter.WriteExpr(value.Value)\n\t}\n\tformatter.WriteString(\"}\")\n}\n\nfunc (n *NamedCollectionParam) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(n.Name)\n\tformatter.WriteString(\" = \")\n\tformatter.WriteExpr(n.Value)\n\tif n.NotOverridable {\n\t\tformatter.WriteString(\" NOT OVERRIDABLE\")\n\t} else if n.Overridable {\n\t\tformatter.WriteString(\" OVERRIDABLE\")\n\t}\n}\n\nfunc (n *NamedParameterExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(n.Name)\n\tformatter.WriteByte('=')\n\tformatter.WriteExpr(n.Value)\n}\n\nfunc (n *NegateExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('-')\n\tformatter.WriteExpr(n.Expr)\n}\n\nfunc (n *NestedIdentifier) FormatSQL(formatter *Formatter) {\n\tif n.DotIdent != nil {\n\t\tformatter.WriteExpr(n.Ident)\n\t\tformatter.WriteByte('.')\n\t\tformatter.WriteExpr(n.DotIdent)\n\t} else {\n\t\tformatter.WriteExpr(n.Ident)\n\t}\n}\n\nfunc (n *NestedType) FormatSQL(formatter *Formatter) {\n\t// on the same level as the column type\n\tformatter.WriteExpr(n.Name)\n\tformatter.WriteByte('(')\n\tfor i, column := range n.Columns {\n\t\tformatter.WriteExpr(column)\n\t\tif i != len(n.Columns)-1 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t}\n\t// right paren needs to be on the same level as the column\n\tformatter.WriteByte(')')\n}\n\nfunc (n *NotExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"NOT\")\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(n.Expr)\n}\n\nfunc (n *NotNullLiteral) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"NOT NULL\")\n}\n\nfunc (n *NullLiteral) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"NULL\")\n}\n\nfunc (n *NumberLiteral) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(n.Literal)\n}\n\nfunc (o *ObjectParams) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(o.Object)\n\tformatter.WriteExpr(o.Params)\n}\n\nfunc (o *OnClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ON \")\n\tformatter.WriteExpr(o.On)\n}\n\nfunc (o *OperationExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(strings.ToUpper(string(o.Kind)))\n}\n\nfunc (o *OptimizeStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"OPTIMIZE TABLE \")\n\tformatter.WriteExpr(o.Table)\n\tif o.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(o.OnCluster)\n\t}\n\tif o.Partition != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(o.Partition)\n\t}\n\tif o.HasFinal {\n\t\tformatter.WriteString(\" FINAL\")\n\t}\n\tif o.Deduplicate != nil {\n\t\tformatter.WriteExpr(o.Deduplicate)\n\t}\n}\n\nfunc (o *OrderByClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ORDER BY\")\n\tformatter.Indent()\n\tfor i, item := range o.Items {\n\t\tif i == 0 {\n\t\t\tformatter.Break()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(item)\n\t}\n\tif o.Interpolate != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(o.Interpolate)\n\t}\n\tformatter.Dedent()\n}\n\nfunc (o *OrderExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(o.Expr)\n\tif o.Alias != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(o.Alias)\n\t}\n\tif o.Direction != OrderDirectionNone {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteString(string(o.Direction))\n\t}\n\tif o.Fill != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(o.Fill)\n\t}\n}\n\nfunc (f *ParamExprList) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"(\")\n\tformatter.WriteExpr(f.Items)\n\tformatter.WriteString(\")\")\n\tif f.ColumnArgList != nil {\n\t\tformatter.WriteExpr(f.ColumnArgList)\n\t}\n}\n\nfunc (p *PartitionByClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"PARTITION BY \")\n\tformatter.WriteExpr(p.Expr)\n}\n\nfunc (p *PartitionClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"PARTITION \")\n\tif p.ID != nil {\n\t\tformatter.WriteExpr(p.ID)\n\t} else if p.All {\n\t\tformatter.WriteString(\"ALL\")\n\t} else {\n\t\tformatter.WriteExpr(p.Expr)\n\t}\n}\n\nfunc (p *Path) FormatSQL(formatter *Formatter) {\n\tfor i, ident := range p.Fields {\n\t\tif i > 0 {\n\t\t\tformatter.WriteByte('.')\n\t\t}\n\t\tformatter.WriteExpr(ident)\n\t}\n}\n\nfunc (p *PlaceHolder) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(p.Type)\n}\n\nfunc (w *PrewhereClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"PREWHERE \")\n\tformatter.WriteExpr(w.Expr)\n}\n\nfunc (p *PrimaryKeyClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"PRIMARY KEY \")\n\tformatter.WriteExpr(p.Expr)\n}\n\nfunc (p *PrivilegeClause) FormatSQL(formatter *Formatter) {\n\tfor i, keyword := range p.Keywords {\n\t\tif i > 0 {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteString(keyword)\n\t}\n\tif p.Params != nil {\n\t\tformatter.WriteExpr(p.Params)\n\t}\n}\n\nfunc (p *ProjectionOrderByClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"ORDER BY \")\n\tformatter.WriteExpr(p.Columns)\n}\n\nfunc (p *ProjectionSelectStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"(\")\n\tif p.With != nil {\n\t\tformatter.WriteExpr(p.With)\n\t\tformatter.WriteByte(whitespace)\n\t}\n\tformatter.WriteString(\"SELECT \")\n\tformatter.WriteExpr(p.SelectColumns)\n\tif p.GroupBy != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(p.GroupBy)\n\t}\n\tif p.OrderBy != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(p.OrderBy)\n\t}\n\tformatter.WriteString(\")\")\n}\n\nfunc (c *PropertyType) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(c.Name)\n}\n\nfunc (q *QueryParam) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"{\")\n\tformatter.WriteExpr(q.Name)\n\tformatter.WriteString(\": \")\n\tformatter.WriteExpr(q.Type)\n\tformatter.WriteString(\"}\")\n}\n\nfunc (r *RatioExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(r.Numerator)\n\tif r.Denominator != nil {\n\t\tformatter.WriteString(\"/\")\n\t\tformatter.WriteExpr(r.Denominator)\n\t}\n}\n\nfunc (r *RefreshExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"REFRESH \")\n\tformatter.WriteString(r.Frequency)\n\tif r.Interval != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(r.Interval)\n\t}\n\tif r.Offset != nil {\n\t\tformatter.WriteString(\" OFFSET \")\n\t\tformatter.WriteExpr(r.Offset)\n\t}\n}\n\nfunc (a *RemovePropertyType) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\" REMOVE \")\n\tformatter.WriteExpr(a.PropertyType)\n}\n\nfunc (r *RenameStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"RENAME \" + r.RenameTarget + \" \")\n\tfor i, pair := range r.TargetPairList {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(pair.Old)\n\t\tformatter.WriteString(\" TO \")\n\t\tformatter.WriteExpr(pair.New)\n\t}\n\tif r.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(r.OnCluster)\n\t}\n}\n\nfunc (r *RoleName) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(r.Name)\n\tif r.Scope != nil {\n\t\tformatter.WriteString(\"@\")\n\t\tformatter.WriteExpr(r.Scope)\n\t}\n\tif r.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(r.OnCluster)\n\t}\n}\n\nfunc (r *RoleRenamePair) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(r.RoleName)\n\tif r.NewName != nil {\n\t\tformatter.WriteString(\" RENAME TO \")\n\t\tformatter.WriteExpr(r.NewName)\n\t}\n}\n\nfunc (r *RoleSetting) FormatSQL(formatter *Formatter) {\n\tfor i, settingPair := range r.SettingPairs {\n\t\tif i > 0 {\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(settingPair)\n\t}\n\tif r.Modifier != nil {\n\t\tif len(r.SettingPairs) > 0 {\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(r.Modifier)\n\t}\n}\n\nfunc (s *SampleByClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SAMPLE BY \")\n\tformatter.WriteExpr(s.Expr)\n}\n\nfunc (s *SampleClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SAMPLE \")\n\tformatter.WriteExpr(s.Ratio)\n\tif s.Offset != nil {\n\t\tformatter.WriteString(\" OFFSET \")\n\t\tformatter.WriteExpr(s.Offset)\n\t}\n}\n\nfunc (s *ScalarType) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(s.Name)\n}\n\nfunc (s *SelectItem) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(s.Expr)\n\tfor _, modifier := range s.Modifiers {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(modifier)\n\t}\n\tif s.Alias != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(s.Alias)\n\t}\n}\n\nfunc (s *SelectQuery) FormatSQL(formatter *Formatter) {\n\tif s.With != nil {\n\t\tformatter.WriteString(\"WITH\")\n\t\tformatter.Indent()\n\t\tfor i, cte := range s.With.CTEs {\n\t\t\tif i == 0 {\n\t\t\t\tformatter.Break()\n\t\t\t} else {\n\t\t\t\tformatter.WriteByte(',')\n\t\t\t\tformatter.Break()\n\t\t\t}\n\t\t\tformatter.WriteExpr(cte)\n\t\t}\n\t\tformatter.Dedent()\n\t\tformatter.Break()\n\t}\n\tformatter.WriteString(\"SELECT\")\n\tif s.HasDistinct {\n\t\tformatter.WriteString(\" DISTINCT\")\n\t\tif s.DistinctOn != nil {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t\tformatter.WriteExpr(s.DistinctOn)\n\t\t}\n\t}\n\tif s.Top != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(s.Top)\n\t}\n\tformatter.Indent()\n\tfor i, selectItem := range s.SelectItems {\n\t\tif i == 0 {\n\t\t\tformatter.Break()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(selectItem)\n\t}\n\tformatter.Dedent()\n\tif s.From != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.From)\n\t}\n\tif s.Window != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Window)\n\t}\n\tif s.Prewhere != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Prewhere)\n\t}\n\tif s.Where != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Where)\n\t}\n\tif s.GroupBy != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.GroupBy)\n\t}\n\tif s.Having != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Having)\n\t}\n\tif s.OrderBy != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.OrderBy)\n\t}\n\tif s.LimitBy != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.LimitBy)\n\t}\n\tif s.Limit != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Limit)\n\t}\n\tif s.Settings != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Settings)\n\t}\n\tif s.Format != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Format)\n\t}\n\tif s.UnionAll != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"UNION ALL\")\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.UnionAll)\n\t} else if s.UnionDistinct != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"UNION DISTINCT\")\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.UnionDistinct)\n\t} else if s.Except != nil {\n\t\tformatter.Break()\n\t\tformatter.WriteString(\"EXCEPT\")\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(s.Except)\n\t}\n}\n\nfunc (s *SetStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SET \")\n\tfor i, item := range s.Settings.Items {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(item)\n\t}\n}\n\nfunc (s *SettingExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(s.Name)\n\tformatter.WriteByte('=')\n\tformatter.WriteExpr(s.Expr)\n}\n\nfunc (s *SettingPair) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(s.Name)\n\tif s.Value != nil {\n\t\tif s.Operation == TokenKindSingleEQ {\n\t\t\tformatter.WriteString(string(s.Operation))\n\t\t} else {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteExpr(s.Value)\n\t}\n}\n\nfunc (s *SettingsClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SETTINGS\")\n\tformatter.Indent()\n\tfor i, item := range s.Items {\n\t\tif i == 0 {\n\t\t\tformatter.Break()\n\t\t} else {\n\t\t\tformatter.WriteByte(',')\n\t\t\tformatter.Break()\n\t\t}\n\t\tformatter.WriteExpr(item)\n\t}\n\tformatter.Dedent()\n}\n\nfunc (s *ShowStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SHOW \")\n\tformatter.WriteString(s.ShowType)\n\tif s.Target != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(s.Target)\n\t}\n\n\t// Add optional clauses for SHOW DATABASES\n\tif s.LikeType != \"\" && s.LikePattern != nil {\n\t\tif s.NotLike {\n\t\t\tformatter.WriteString(\" NOT \")\n\t\t} else {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteString(s.LikeType)\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(s.LikePattern)\n\t}\n\n\tif s.Limit != nil {\n\t\tformatter.WriteString(\" LIMIT \")\n\t\tformatter.WriteExpr(s.Limit)\n\t}\n\n\tif s.OutFile != nil {\n\t\tformatter.WriteString(\" INTO OUTFILE \")\n\t\tformatter.WriteExpr(s.OutFile)\n\t}\n\n\tif s.Format != nil {\n\t\tformatter.WriteString(\" FORMAT \")\n\t\tformatter.WriteExpr(s.Format)\n\t}\n\n}\n\nfunc (s *StringLiteral) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('\\'')\n\tformatter.WriteString(s.Literal)\n\tformatter.WriteByte('\\'')\n}\n\nfunc (s *SubQuery) FormatSQL(formatter *Formatter) {\n\tif s.HasParen {\n\t\tformatter.WriteByte('(')\n\t}\n\tformatter.WriteExpr(s.Select)\n\tif s.HasParen {\n\t\tformatter.WriteByte(')')\n\t}\n}\n\nfunc (s *SystemCtrlExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(s.Command)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteString(s.Type)\n\tif s.Cluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(s.Cluster)\n\t}\n}\n\nfunc (s *SystemDropExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"DROP \")\n\tformatter.WriteString(s.Type)\n}\n\nfunc (s *SystemFlushExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"FLUSH \")\n\tif s.Logs {\n\t\tformatter.WriteString(\"LOGS\")\n\t} else {\n\t\tformatter.WriteExpr(s.Distributed)\n\t}\n}\n\nfunc (s *SystemReloadExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"RELOAD \")\n\tformatter.WriteString(s.Type)\n\tif s.Dictionary != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(s.Dictionary)\n\t}\n}\n\nfunc (s *SystemStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SYSTEM\")\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(s.Expr)\n}\n\nfunc (s *SystemSyncExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"SYNC \")\n\tformatter.WriteExpr(s.Cluster)\n}\n\nfunc (t *TTLClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"TTL \")\n\tfor i, item := range t.Items {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(item)\n\t}\n}\n\nfunc (t *TTLExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(t.Expr)\n\tif t.Policy != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(t.Policy)\n\t}\n}\n\nfunc (t *TTLPolicy) FormatSQL(formatter *Formatter) {\n\n\tif t.Item != nil {\n\t\tformatter.WriteExpr(t.Item)\n\t}\n\tif t.Where != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(t.Where)\n\t}\n\tif t.GroupBy != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(t.GroupBy)\n\t}\n}\n\nfunc (t *TTLPolicyRule) FormatSQL(formatter *Formatter) {\n\tif t.ToVolume != nil {\n\t\tformatter.WriteString(\"TO VOLUME \")\n\t\tformatter.WriteExpr(t.ToVolume)\n\t} else if t.ToDisk != nil {\n\t\tformatter.WriteString(\"TO DISK \")\n\t\tformatter.WriteExpr(t.ToDisk)\n\t} else if t.Action != nil {\n\t\tformatter.WriteExpr(t.Action)\n\t}\n}\n\nfunc (t *TTLPolicyRuleAction) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(t.Action)\n\tif t.Codec != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(t.Codec)\n\t}\n}\n\nfunc (t *TableArgListExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\tfor i, arg := range t.Args {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(arg)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (t *TableExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(t.Expr)\n\tif t.Alias != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(t.Alias)\n\t}\n\tif t.HasFinal {\n\t\tformatter.WriteString(\" FINAL\")\n\t}\n}\n\nfunc (t *TableFunctionExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(t.Name)\n\tformatter.WriteExpr(t.Args)\n}\n\nfunc (t *TableIdentifier) FormatSQL(formatter *Formatter) {\n\tif t.Database != nil {\n\t\tformatter.WriteExpr(t.Database)\n\t\tformatter.WriteByte('.')\n\t}\n\tformatter.WriteExpr(t.Table)\n}\n\nfunc (a *TableIndex) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"INDEX\")\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(a.Name)\n\t// Add space only if column expression doesn't start with '('\n\tcolumnExprStr := Format(a.ColumnExpr)\n\tif len(columnExprStr) > 0 && columnExprStr[0] != '(' {\n\t\tformatter.WriteByte(whitespace)\n\t}\n\tformatter.WriteString(columnExprStr)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteString(\"TYPE\")\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(a.ColumnType)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteString(\"GRANULARITY\")\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(a.Granularity)\n}\n\nfunc (t *TableProjection) FormatSQL(formatter *Formatter) {\n\tif t.IncludeProjectionKeyword {\n\t\tformatter.WriteString(\"PROJECTION \")\n\t}\n\tformatter.WriteExpr(t.Identifier)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(t.Select)\n}\n\nfunc (t *TableSchemaClause) FormatSQL(formatter *Formatter) {\n\tif len(t.Columns) > 0 {\n\t\tformatter.WriteByte('(')\n\t\tformatter.Indent()\n\t\tfor i, column := range t.Columns {\n\t\t\tif i == 0 {\n\t\t\t\tformatter.NewLine()\n\t\t\t} else {\n\t\t\t\tformatter.WriteByte(',')\n\t\t\t\tformatter.Break()\n\t\t\t}\n\t\t\tformatter.WriteExpr(column)\n\t\t}\n\t\tformatter.Dedent()\n\t\tformatter.NewLine()\n\t\tformatter.WriteByte(')')\n\t}\n\tif t.AliasTable != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(t.AliasTable)\n\t}\n\tif t.TableFunction != nil {\n\t\tformatter.WriteString(\" AS \")\n\t\tformatter.WriteExpr(t.TableFunction)\n\t}\n}\n\nfunc (t *TargetPair) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(t.Old)\n\tformatter.WriteString(\" TO \")\n\tformatter.WriteExpr(t.New)\n}\n\nfunc (t *TernaryOperation) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(t.Condition)\n\tformatter.WriteString(\" ? \")\n\tformatter.WriteExpr(t.TrueExpr)\n\tformatter.WriteString(\" : \")\n\tformatter.WriteExpr(t.FalseExpr)\n}\n\nfunc (t *TopClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"TOP \")\n\tformatter.WriteString(t.Number.Literal)\n\tif t.WithTies {\n\t\tformatter.WriteString(\" WITH TIES\")\n\t}\n}\n\nfunc (t *TruncateTable) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"TRUNCATE \")\n\tif t.IsTemporary {\n\t\tformatter.WriteString(\"TEMPORARY \")\n\t}\n\tformatter.WriteString(\"TABLE \")\n\tif t.IfExists {\n\t\tformatter.WriteString(\"IF EXISTS \")\n\t}\n\tformatter.WriteExpr(t.Name)\n\tif t.OnCluster != nil {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteExpr(t.OnCluster)\n\t}\n}\n\nfunc (s *TypeWithParams) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(s.Name)\n\tformatter.WriteByte('(')\n\tfor i, size := range s.Params {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(size)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (t *TypedPlaceholder) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"{\")\n\tformatter.WriteExpr(t.Name)\n\tformatter.WriteByte(':')\n\tformatter.WriteExpr(t.Type)\n\tformatter.WriteString(\"}\")\n}\n\nfunc (u *UUID) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"UUID \")\n\tformatter.WriteExpr(u.Value)\n}\n\nfunc (n *UnaryExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(string(n.Kind))\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(n.Expr)\n}\n\nfunc (u *UpdateAssignment) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(u.Column)\n\tformatter.WriteString(\" = \")\n\tformatter.WriteExpr(u.Expr)\n}\n\nfunc (u *UseStmt) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"USE \")\n\tformatter.WriteExpr(u.Database)\n}\n\nfunc (u *UsingClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"USING \")\n\tformatter.WriteExpr(u.Using)\n}\n\nfunc (w *WhenClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"WHEN \")\n\tformatter.WriteExpr(w.When)\n\tformatter.WriteString(\" THEN \")\n\tformatter.WriteExpr(w.Then)\n\tif w.Else != nil {\n\t\tformatter.WriteString(\" ELSE \")\n\t\tformatter.WriteExpr(w.Else)\n\t}\n}\n\nfunc (w *WhereClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"WHERE\")\n\tif isLogicalBinaryOp(w.Expr) {\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(w.Expr)\n\t} else {\n\t\tformatter.Indent()\n\t\tformatter.Break()\n\t\tformatter.WriteExpr(w.Expr)\n\t\tformatter.Dedent()\n\t}\n}\n\nfunc (w *WindowDefinition) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(w.Name)\n\tformatter.WriteString(\" AS \")\n\tformatter.WriteExpr(w.Expr)\n}\n\nfunc (w *WindowClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"WINDOW \")\n\tfor i, window := range w.Windows {\n\t\twindow.FormatSQL(formatter)\n\t\tif i != len(w.Windows)-1 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t}\n}\n\nfunc (w *WindowExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteByte('(')\n\thasPart := false\n\tif w.WindowName != nil {\n\t\tformatter.WriteExpr(w.WindowName)\n\t\thasPart = true\n\t}\n\tif w.PartitionBy != nil {\n\t\tif hasPart {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteExpr(w.PartitionBy)\n\t\thasPart = true\n\t}\n\tif w.OrderBy != nil {\n\t\tif hasPart {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteExpr(w.OrderBy)\n\t\thasPart = true\n\t}\n\tif w.Frame != nil {\n\t\tif hasPart {\n\t\t\tformatter.WriteByte(whitespace)\n\t\t}\n\t\tformatter.WriteExpr(w.Frame)\n\t}\n\tformatter.WriteByte(')')\n}\n\nfunc (f *WindowFrameClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(f.Type)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteExpr(f.Extend)\n}\n\nfunc (f *WindowFrameCurrentRow) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"CURRENT ROW\")\n}\n\nfunc (f *WindowFrameExtendExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(f.Expr)\n\tif f.Direction != \"\" {\n\t\tformatter.WriteByte(whitespace)\n\t\tformatter.WriteString(f.Direction)\n\t}\n}\n\nfunc (f *WindowFrameNumber) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(f.Number)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteString(f.Direction)\n}\n\nfunc (f *WindowFrameParam) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(f.Param)\n\tformatter.WriteByte(whitespace)\n\tformatter.WriteString(f.Direction)\n}\n\nfunc (f *WindowFrameUnbounded) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"UNBOUNDED \")\n\tformatter.WriteString(f.Direction)\n}\n\nfunc (w *WindowFunctionExpr) FormatSQL(formatter *Formatter) {\n\tformatter.WriteExpr(w.Function)\n\tformatter.WriteString(\" OVER \")\n\tformatter.WriteExpr(w.OverExpr)\n}\n\nfunc (w *WithClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"WITH \")\n\tfor i, cte := range w.CTEs {\n\t\tif i > 0 {\n\t\t\tformatter.WriteString(\", \")\n\t\t}\n\t\tformatter.WriteExpr(cte)\n\t}\n}\n\nfunc (w *WithTimeoutClause) FormatSQL(formatter *Formatter) {\n\tformatter.WriteString(\"WITH TIMEOUT \")\n\tformatter.WriteExpr(w.Number)\n}\n"
  },
  {
    "path": "parser/format_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestFormatter_WithBeautify_Chaining(t *testing.T) {\n\t// Test that WithBeautify returns the formatter for chaining\n\tformatter := NewFormatter().WithBeautify()\n\trequire.NotNil(t, formatter)\n\trequire.Equal(t, FormatModeBeautify, formatter.mode)\n}\n\nfunc TestFormatter_WithIndent_Chaining(t *testing.T) {\n\t// Test that WithIndent returns the formatter for chaining\n\tformatter := NewFormatter().WithIndent(\"    \")\n\trequire.NotNil(t, formatter)\n\trequire.Equal(t, \"    \", formatter.indent)\n}\n\nfunc TestFormatter_ChainedMethods(t *testing.T) {\n\t// Test that methods can be chained together\n\tformatter := NewFormatter().WithBeautify().WithIndent(\"\\t\")\n\trequire.NotNil(t, formatter)\n\trequire.Equal(t, FormatModeBeautify, formatter.mode)\n\trequire.Equal(t, \"\\t\", formatter.indent)\n}\n\nfunc TestFormatter_WithIndent_CustomIndentation(t *testing.T) {\n\t// Test actual formatting with custom indent using parsed SQL\n\tsql := \"SELECT col1, col2 FROM table1 WHERE col1 > 10\"\n\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Len(t, stmts, 1)\n\n\t// Test with default 2-space indent\n\tformatter1 := NewFormatter().WithBeautify()\n\tformatter1.WriteExpr(stmts[0])\n\tresult1 := formatter1.String()\n\n\t// Test with 4-space indent\n\tformatter2 := NewFormatter().WithBeautify().WithIndent(\"    \")\n\tformatter2.WriteExpr(stmts[0])\n\tresult2 := formatter2.String()\n\n\t// Test with tab indent\n\tformatter3 := NewFormatter().WithBeautify().WithIndent(\"\\t\")\n\tformatter3.WriteExpr(stmts[0])\n\tresult3 := formatter3.String()\n\n\t// Verify all results are different (due to different indentation)\n\trequire.NotEqual(t, result1, result2)\n\trequire.NotEqual(t, result1, result3)\n\trequire.NotEqual(t, result2, result3)\n\n\t// Verify they all contain the basic SQL keywords\n\trequire.Contains(t, result1, \"SELECT\")\n\trequire.Contains(t, result2, \"SELECT\")\n\trequire.Contains(t, result3, \"SELECT\")\n\trequire.Contains(t, result1, \"FROM\")\n\trequire.Contains(t, result2, \"FROM\")\n\trequire.Contains(t, result3, \"FROM\")\n}\n\nfunc TestFormatter_DefaultIndent(t *testing.T) {\n\t// Test that default indent is 2 spaces\n\tformatter := NewFormatter()\n\trequire.Equal(t, \"  \", formatter.indent)\n}\n"
  },
  {
    "path": "parser/helper.go",
    "content": "package parser\n\nfunc IsDigit(c byte) bool {\n\treturn '0' <= c && c <= '9'\n}\n\nfunc IsHexDigit(c byte) bool {\n\treturn '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F'\n}\n\nfunc IsIdentStart(c byte) bool {\n\treturn 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_'\n}\n\nfunc IsIdentPart(c byte) bool {\n\treturn '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '$'\n}\n"
  },
  {
    "path": "parser/keyword.go",
    "content": "package parser\n\nconst (\n\tKeywordAdd          = \"ADD\"\n\tKeywordAdmin        = \"ADMIN\"\n\tKeywordAfter        = \"AFTER\"\n\tKeywordAlias        = \"ALIAS\"\n\tKeywordAll          = \"ALL\"\n\tKeywordAlter        = \"ALTER\"\n\tKeywordAnd          = \"AND\"\n\tKeywordAnti         = \"ANTI\"\n\tKeywordAny          = \"ANY\"\n\tKeywordAppend       = \"APPEND\"\n\tKeywordApply        = \"APPLY\"\n\tKeywordArray        = \"ARRAY\"\n\tKeywordAs           = \"AS\"\n\tKeywordAsc          = \"ASC\"\n\tKeywordAscending    = \"ASCENDING\"\n\tKeywordAsof         = \"ASOF\"\n\tKeywordAst          = \"AST\"\n\tKeywordAsync        = \"ASYNC\"\n\tKeywordAttach       = \"ATTACH\"\n\tKeywordBetween      = \"BETWEEN\"\n\tKeywordBoth         = \"BOTH\"\n\tKeywordBy           = \"BY\"\n\tKeywordCache        = \"CACHE\"\n\tKeywordCase         = \"CASE\"\n\tKeywordCast         = \"CAST\"\n\tKeywordCheck        = \"CHECK\"\n\tKeywordClear        = \"CLEAR\"\n\tKeywordCluster      = \"CLUSTER\"\n\tKeywordCodec        = \"CODEC\"\n\tKeywordCollate      = \"COLLATE\"\n\tKeywordCollection   = \"COLLECTION\"\n\tKeywordColumn       = \"COLUMN\"\n\tKeywordColumns      = \"COLUMNS\"\n\tKeywordComment      = \"COMMENT\"\n\tKeywordCompiled     = \"COMPILED\"\n\tKeywordConfig       = \"CONFIG\"\n\tKeywordConstraint   = \"CONSTRAINT\"\n\tKeywordCreate       = \"CREATE\"\n\tKeywordCross        = \"CROSS\"\n\tKeywordCube         = \"CUBE\"\n\tKeywordCurrent      = \"CURRENT\"\n\tKeywordDatabase     = \"DATABASE\"\n\tKeywordDatabases    = \"DATABASES\"\n\tKeywordDate         = \"DATE\"\n\tKeywordDay          = \"DAY\"\n\tKeywordDeduplicate  = \"DEDUPLICATE\"\n\tKeywordDefault      = \"DEFAULT\"\n\tKeywordDelay        = \"DELAY\"\n\tKeywordDelete       = \"DELETE\"\n\tKeywordDepends      = \"DEPENDS\"\n\tKeywordDesc         = \"DESC\"\n\tKeywordDescending   = \"DESCENDING\"\n\tKeywordDescribe     = \"DESCRIBE\"\n\tKeywordDetach       = \"DETACH\"\n\tKeywordDetached     = \"DETACHED\"\n\tKeywordDictionaries = \"DICTIONARIES\"\n\tKeywordDictionary   = \"DICTIONARY\"\n\tKeywordDisk         = \"DISK\"\n\tKeywordDistinct     = \"DISTINCT\"\n\tKeywordDistributed  = \"DISTRIBUTED\"\n\tKeywordDrop         = \"DROP\"\n\tKeywordDNS          = \"DNS\"\n\tKeywordElse         = \"ELSE\"\n\tKeywordEmbedded     = \"EMBEDDED\"\n\tKeywordEmpty        = \"EMPTY\"\n\tKeywordEnd          = \"END\"\n\tKeywordEngine       = \"ENGINE\"\n\tKeywordEstimate     = \"ESTIMATE\"\n\tKeywordEvents       = \"EVENTS\"\n\tKeywordEvery        = \"EVERY\"\n\tKeywordExcept       = \"EXCEPT\"\n\tKeywordExists       = \"EXISTS\"\n\tKeywordExplain      = \"EXPLAIN\"\n\tKeywordExpression   = \"EXPRESSION\"\n\tKeywordExtract      = \"EXTRACT\"\n\tKeywordFalse        = \"FALSE\"\n\tKeywordFetches      = \"FETCHES\"\n\tKeywordFileSystem   = \"FILESYSTEM\"\n\tKeywordFill         = \"FILL\"\n\tKeywordFinal        = \"FINAL\"\n\tKeywordFirst        = \"FIRST\"\n\tKeywordFlush        = \"FLUSH\"\n\tKeywordFollowing    = \"FOLLOWING\"\n\tKeywordFor          = \"FOR\"\n\tKeywordFormat       = \"FORMAT\"\n\tKeywordFreeze       = \"FREEZE\"\n\tKeywordFrom         = \"FROM\"\n\tKeywordFull         = \"FULL\"\n\tKeywordFunction     = \"FUNCTION\"\n\tKeywordFunctions    = \"FUNCTIONS\"\n\tKeywordGlobal       = \"GLOBAL\"\n\tKeywordGrant        = \"GRANT\"\n\tKeywordGrantees     = \"GRANTEES\"\n\tKeywordGranularity  = \"GRANULARITY\"\n\tKeywordGroup        = \"GROUP\"\n\tKeywordGrouping     = \"GROUPING\"\n\tKeywordHaving       = \"HAVING\"\n\tKeywordHierarchical = \"HIERARCHICAL\"\n\tKeywordHost         = \"HOST\"\n\tKeywordHour         = \"HOUR\"\n\tKeywordId           = \"ID\"\n\tKeywordIdentified   = \"IDENTIFIED\"\n\tKeywordIf           = \"IF\"\n\tKeywordIlike        = \"ILIKE\"\n\tKeywordIn           = \"IN\"\n\tKeywordIndex        = \"INDEX\"\n\tKeywordInf          = \"INF\"\n\tKeywordInjective    = \"INJECTIVE\"\n\tKeywordInner        = \"INNER\"\n\tKeywordInsert       = \"INSERT\"\n\tKeywordInterval     = \"INTERVAL\"\n\tKeywordInterpolate  = \"INTERPOLATE\"\n\tKeywordInto         = \"INTO\"\n\tKeywordIp           = \"IP\"\n\tKeywordIs           = \"IS\"\n\tKeywordIs_object_id = \"IS_OBJECT_ID\"\n\tKeywordJoin         = \"JOIN\"\n\tKeywordJSON         = \"JSON\"\n\tKeywordKey          = \"KEY\"\n\tKeywordKill         = \"KILL\"\n\tKeywordKerberos     = \"KERBEROS\"\n\tKeywordLast         = \"LAST\"\n\tKeywordLayout       = \"LAYOUT\"\n\tKeywordLdap         = \"LDAP\"\n\tKeywordLeading      = \"LEADING\"\n\tKeywordLeft         = \"LEFT\"\n\tKeywordLifetime     = \"LIFETIME\"\n\tKeywordLike         = \"LIKE\"\n\tKeywordLimit        = \"LIMIT\"\n\tKeywordLive         = \"LIVE\"\n\tKeywordLocal        = \"LOCAL\"\n\tKeywordLogs         = \"LOGS\"\n\tKeywordMark         = \"MARK\"\n\tKeywordMaterialize  = \"MATERIALIZE\"\n\tKeywordMaterialized = \"MATERIALIZED\"\n\tKeywordMax          = \"MAX\"\n\tKeywordMerges       = \"MERGES\"\n\tKeywordMin          = \"MIN\"\n\tKeywordMinute       = \"MINUTE\"\n\tKeywordModify       = \"MODIFY\"\n\tKeywordMonth        = \"MONTH\"\n\tKeywordMove         = \"MOVE\"\n\tKeywordMoves        = \"MOVES\"\n\tKeywordMutation     = \"MUTATION\"\n\tKeywordName         = \"NAME\"\n\tKeywordNamed        = \"NAMED\"\n\tKeywordNan_sql      = \"NAN_SQL\"\n\tKeywordNo           = \"NO\"\n\tKeywordNone         = \"NONE\"\n\tKeywordNot          = \"NOT\"\n\tKeywordNull         = \"NULL\"\n\tKeywordNulls        = \"NULLS\"\n\tKeywordOffset       = \"OFFSET\"\n\tKeywordOn           = \"ON\"\n\tKeywordOptimize     = \"OPTIMIZE\"\n\tKeywordOption       = \"OPTION\"\n\tKeywordOr           = \"OR\"\n\tKeywordOrder        = \"ORDER\"\n\tKeywordOverridable  = \"OVERRIDABLE\"\n\tKeywordOuter        = \"OUTER\"\n\tKeywordOutfile      = \"OUTFILE\"\n\tKeywordOver         = \"OVER\"\n\tKeywordPartition    = \"PARTITION\"\n\tKeywordPipeline     = \"PIPELINE\"\n\tKeywordPolicy       = \"POLICY\"\n\tKeywordPopulate     = \"POPULATE\"\n\tKeywordPreceding    = \"PRECEDING\"\n\tKeywordPrewhere     = \"PREWHERE\"\n\tKeywordPrimary      = \"PRIMARY\"\n\tKeywordProjection   = \"PROJECTION\"\n\tKeywordQuarter      = \"QUARTER\"\n\tKeywordQuery        = \"QUERY\"\n\tKeywordQueues       = \"QUEUES\"\n\tKeywordQuota        = \"QUOTA\"\n\tKeywordRandomize    = \"RANDOMIZE\"\n\tKeywordRange        = \"RANGE\"\n\tKeywordRealm        = \"REALM\"\n\tKeywordRecompress   = \"RECOMPRESS\"\n\tKeywordRefresh      = \"REFRESH\"\n\tKeywordRegexp       = \"REGEXP\"\n\tKeywordReload       = \"RELOAD\"\n\tKeywordRemove       = \"REMOVE\"\n\tKeywordRename       = \"RENAME\"\n\tKeywordReplace      = \"REPLACE\"\n\tKeywordReset        = \"RESET\"\n\tKeywordReplica      = \"REPLICA\"\n\tKeywordReplicated   = \"REPLICATED\"\n\tKeywordReplication  = \"REPLICATION\"\n\tKeywordRestart      = \"RESTART\"\n\tKeywordRight        = \"RIGHT\"\n\tKeywordRole         = \"ROLE\"\n\tKeywordRollup       = \"ROLLUP\"\n\tKeywordRow          = \"ROW\"\n\tKeywordRows         = \"ROWS\"\n\tKeywordSample       = \"SAMPLE\"\n\tKeywordSecond       = \"SECOND\"\n\tKeywordSelect       = \"SELECT\"\n\tKeywordSemi         = \"SEMI\"\n\tKeywordSends        = \"SENDS\"\n\tKeywordServer       = \"SERVER\"\n\tKeywordSet          = \"SET\"\n\tKeywordSets         = \"SETS\"\n\tKeywordSetting      = \"SETTING\"\n\tKeywordSettings     = \"SETTINGS\"\n\tKeywordShow         = \"SHOW\"\n\tKeywordShutdown     = \"SHUTDOWN\"\n\tKeywordSkip         = \"SKIP\"\n\tKeywordSource       = \"SOURCE\"\n\tKeywordStart        = \"START\"\n\tKeywordStaleness    = \"STALENESS\"\n\tKeywordStep         = \"STEP\"\n\tKeywordStop         = \"STOP\"\n\tKeywordSubstring    = \"SUBSTRING\"\n\tKeywordSync         = \"SYNC\"\n\tKeywordSyntax       = \"SYNTAX\"\n\tKeywordSystem       = \"SYSTEM\"\n\tKeywordTable        = \"TABLE\"\n\tKeywordTables       = \"TABLES\"\n\tKeywordTemporary    = \"TEMPORARY\"\n\tKeywordTest         = \"TEST\"\n\tKeywordThen         = \"THEN\"\n\tKeywordTies         = \"TIES\"\n\tKeywordTimeout      = \"TIMEOUT\"\n\tKeywordTimestamp    = \"TIMESTAMP\"\n\tKeywordTo           = \"TO\"\n\tKeywordTop          = \"TOP\"\n\tKeywordTotals       = \"TOTALS\"\n\tKeywordTrailing     = \"TRAILING\"\n\tKeywordTrim         = \"TRIM\"\n\tKeywordTrue         = \"TRUE\"\n\tKeywordTruncate     = \"TRUNCATE\"\n\tKeywordTtl          = \"TTL\"\n\tKeywordType         = \"TYPE\"\n\tKeywordUnbounded    = \"UNBOUNDED\"\n\tKeywordUncompressed = \"UNCOMPRESSED\"\n\tKeywordUnion        = \"UNION\"\n\tKeywordUpdate       = \"UPDATE\"\n\tKeywordUse          = \"USE\"\n\tKeywordUser         = \"USER\"\n\tKeywordUsing        = \"USING\"\n\tKeywordUntil        = \"UNTIL\"\n\tKeywordUuid         = \"UUID\"\n\tKeywordValid        = \"VALID\"\n\tKeywordValues       = \"VALUES\"\n\tKeywordView         = \"VIEW\"\n\tKeywordVolume       = \"VOLUME\"\n\tKeywordWatch        = \"WATCH\"\n\tKeywordWeek         = \"WEEK\"\n\tKeywordWhen         = \"WHEN\"\n\tKeywordWhere        = \"WHERE\"\n\tKeywordWindow       = \"WINDOW\"\n\tKeywordWith         = \"WITH\"\n\tKeywordYear         = \"YEAR\"\n\tKeywordDefiner      = \"DEFINER\"\n\tKeywordSQL          = \"SQL\"\n\tKeywordSecurity     = \"SECURITY\"\n)\n\nvar keywords = NewSet(\n\tKeywordAdd,\n\tKeywordAdmin,\n\tKeywordAfter,\n\tKeywordAlias,\n\tKeywordAll,\n\tKeywordAlter,\n\tKeywordAnd,\n\tKeywordAnti,\n\tKeywordAny,\n\tKeywordAppend,\n\tKeywordApply,\n\tKeywordArray,\n\tKeywordAs,\n\tKeywordAsc,\n\tKeywordAscending,\n\tKeywordAsof,\n\tKeywordAst,\n\tKeywordAsync,\n\tKeywordAttach,\n\tKeywordBetween,\n\tKeywordBoth,\n\tKeywordBy,\n\tKeywordCache,\n\tKeywordCase,\n\tKeywordCast,\n\tKeywordCheck,\n\tKeywordClear,\n\tKeywordCluster,\n\tKeywordCodec,\n\tKeywordCollate,\n\tKeywordCollection,\n\tKeywordColumn,\n\tKeywordColumns,\n\tKeywordComment,\n\tKeywordCompiled,\n\tKeywordConfig,\n\tKeywordConstraint,\n\tKeywordCreate,\n\tKeywordCross,\n\tKeywordCube,\n\tKeywordCurrent,\n\tKeywordDatabase,\n\tKeywordDatabases,\n\tKeywordDate,\n\tKeywordDay,\n\tKeywordDeduplicate,\n\tKeywordDefault,\n\tKeywordDelay,\n\tKeywordDelete,\n\tKeywordDepends,\n\tKeywordDesc,\n\tKeywordDescending,\n\tKeywordDescribe,\n\tKeywordDetach,\n\tKeywordDetached,\n\tKeywordDictionaries,\n\tKeywordDictionary,\n\tKeywordDisk,\n\tKeywordDistinct,\n\tKeywordDistributed,\n\tKeywordDrop,\n\tKeywordDNS,\n\tKeywordElse,\n\tKeywordEnd,\n\tKeywordEngine,\n\tKeywordEstimate,\n\tKeywordEmbedded,\n\tKeywordEmpty,\n\tKeywordEvents,\n\tKeywordEvery,\n\tKeywordExcept,\n\tKeywordExists,\n\tKeywordExplain,\n\tKeywordExpression,\n\tKeywordExtract,\n\tKeywordFalse,\n\tKeywordFetches,\n\tKeywordFileSystem,\n\tKeywordFill,\n\tKeywordFinal,\n\tKeywordFirst,\n\tKeywordFlush,\n\tKeywordFollowing,\n\tKeywordFor,\n\tKeywordFormat,\n\tKeywordFreeze,\n\tKeywordFrom,\n\tKeywordFull,\n\tKeywordFunction,\n\tKeywordFunctions,\n\tKeywordGlobal,\n\tKeywordGrant,\n\tKeywordGrantees,\n\tKeywordGranularity,\n\tKeywordGroup,\n\tKeywordGrouping,\n\tKeywordHaving,\n\tKeywordHierarchical,\n\tKeywordHost,\n\tKeywordHour,\n\tKeywordId,\n\tKeywordIdentified,\n\tKeywordIf,\n\tKeywordIlike,\n\tKeywordIn,\n\tKeywordIndex,\n\tKeywordInf,\n\tKeywordInjective,\n\tKeywordInner,\n\tKeywordInsert,\n\tKeywordInterval,\n\tKeywordInterpolate,\n\tKeywordInto,\n\tKeywordIp,\n\tKeywordIs,\n\tKeywordIs_object_id,\n\tKeywordJoin,\n\tKeywordJSON,\n\tKeywordKey,\n\tKeywordKill,\n\tKeywordKerberos,\n\tKeywordLast,\n\tKeywordLayout,\n\tKeywordLdap,\n\tKeywordLeading,\n\tKeywordLeft,\n\tKeywordLifetime,\n\tKeywordLike,\n\tKeywordLimit,\n\tKeywordLive,\n\tKeywordLocal,\n\tKeywordLogs,\n\tKeywordMark,\n\tKeywordMaterialize,\n\tKeywordMaterialized,\n\tKeywordMax,\n\tKeywordMerges,\n\tKeywordMin,\n\tKeywordMinute,\n\tKeywordModify,\n\tKeywordMonth,\n\tKeywordMove,\n\tKeywordMoves,\n\tKeywordMutation,\n\tKeywordName,\n\tKeywordNamed,\n\tKeywordNan_sql,\n\tKeywordNo,\n\tKeywordNone,\n\tKeywordNot,\n\tKeywordNull,\n\tKeywordNulls,\n\tKeywordOffset,\n\tKeywordOn,\n\tKeywordOptimize,\n\tKeywordOption,\n\tKeywordOr,\n\tKeywordOrder,\n\tKeywordOuter,\n\tKeywordOverridable,\n\tKeywordOutfile,\n\tKeywordOver,\n\tKeywordPartition,\n\tKeywordPipeline,\n\tKeywordPolicy,\n\tKeywordPopulate,\n\tKeywordPreceding,\n\tKeywordPrewhere,\n\tKeywordPrimary,\n\tKeywordProjection,\n\tKeywordQuarter,\n\tKeywordQuery,\n\tKeywordQueues,\n\tKeywordQuota,\n\tKeywordRandomize,\n\tKeywordRange,\n\tKeywordRealm,\n\tKeywordRecompress,\n\tKeywordRefresh,\n\tKeywordRegexp,\n\tKeywordReload,\n\tKeywordRemove,\n\tKeywordRename,\n\tKeywordReplace,\n\tKeywordReset,\n\tKeywordReplica,\n\tKeywordReplicated,\n\tKeywordReplication,\n\tKeywordRestart,\n\tKeywordRight,\n\tKeywordRole,\n\tKeywordRollup,\n\tKeywordRow,\n\tKeywordRows,\n\tKeywordSample,\n\tKeywordSecond,\n\tKeywordSelect,\n\tKeywordSemi,\n\tKeywordSends,\n\tKeywordServer,\n\tKeywordSet,\n\tKeywordSets,\n\tKeywordSetting,\n\tKeywordSettings,\n\tKeywordShow,\n\tKeywordShutdown,\n\tKeywordSkip,\n\tKeywordSource,\n\tKeywordStart,\n\tKeywordStaleness,\n\tKeywordStep,\n\tKeywordStop,\n\tKeywordSubstring,\n\tKeywordSync,\n\tKeywordSyntax,\n\tKeywordSystem,\n\tKeywordTable,\n\tKeywordTables,\n\tKeywordTemporary,\n\tKeywordTest,\n\tKeywordThen,\n\tKeywordTies,\n\tKeywordTimeout,\n\tKeywordTimestamp,\n\tKeywordTo,\n\tKeywordTop,\n\tKeywordTotals,\n\tKeywordTrailing,\n\tKeywordTrim,\n\tKeywordTrue,\n\tKeywordTruncate,\n\tKeywordTtl,\n\tKeywordType,\n\tKeywordUnbounded,\n\tKeywordUncompressed,\n\tKeywordUnion,\n\tKeywordUpdate,\n\tKeywordUse,\n\tKeywordUser,\n\tKeywordUsing,\n\tKeywordUntil,\n\tKeywordUuid,\n\tKeywordValid,\n\tKeywordValues,\n\tKeywordView,\n\tKeywordVolume,\n\tKeywordWatch,\n\tKeywordWeek,\n\tKeywordWhen,\n\tKeywordWhere,\n\tKeywordWindow,\n\tKeywordWith,\n\tKeywordYear,\n\tKeywordDefiner,\n\tKeywordSQL,\n\tKeywordSecurity,\n)\n"
  },
  {
    "path": "parser/lexer.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nconst (\n\tTokenKindEOF          TokenKind = \"<eof>\"\n\tTokenKindIdent        TokenKind = \"<ident>\"\n\tTokenKindKeyword      TokenKind = \"<keyword>\"\n\tTokenKindInt          TokenKind = \"<int>\"\n\tTokenKindFloat        TokenKind = \"<float>\"\n\tTokenKindString       TokenKind = \"<string>\"\n\tTokenKindDot                    = \".\"\n\tTokenKindSingleEQ     TokenKind = \"=\"\n\tTokenKindDoubleEQ     TokenKind = \"==\"\n\tTokenKindNE           TokenKind = \"!=\"\n\tTokenKindLT           TokenKind = \"<\"\n\tTokenKindLE           TokenKind = \"<=\"\n\tTokenKindGT           TokenKind = \">\"\n\tTokenKindGE           TokenKind = \">=\"\n\tTokenKindQuestionMark TokenKind = \"?\"\n\n\tTokenKindPlus   TokenKind = \"+\"\n\tTokenKindMinus  TokenKind = \"-\"\n\tTokenKindMul    TokenKind = \"*\"\n\tTokenKindDiv    TokenKind = \"/\"\n\tTokenKindMod    TokenKind = \"%\"\n\tTokenKindConcat TokenKind = \"||\"\n\n\tTokenKindArrow TokenKind = \"->\"\n\tTokenKindDash  TokenKind = \"::\"\n\n\tTokenKindLParen   TokenKind = \"(\"\n\tTokenKindRParen   TokenKind = \")\"\n\tTokenKindLBrace   TokenKind = \"{\"\n\tTokenKindRBrace   TokenKind = \"}\"\n\tTokenKindLBracket TokenKind = \"[\"\n\tTokenKindRBracket TokenKind = \"]\"\n\n\tTokenKindComma  TokenKind = \",\"\n\tTokenKindColon  TokenKind = \":\"\n\tTokenKindAtSign TokenKind = \"@\"\n)\n\nconst (\n\tUnquoted = iota + 1\n\tDoubleQuote\n\tBackTicks\n\tSingleQuote\n)\n\ntype Pos int\ntype TokenKind string\n\ntype Token struct {\n\tPos Pos\n\tEnd Pos\n\n\tKind      TokenKind\n\tString    string\n\tBase      int // 10 or 16 on TokenKindInt\n\tQuoteType int\n}\n\nfunc (t *Token) ToString() string {\n\tif t.Kind == TokenKindKeyword {\n\t\treturn strings.ToUpper(t.String)\n\t}\n\treturn t.String\n}\n\ntype lexerState struct {\n\tcurrent   int\n\tlastToken *Token\n}\n\ntype Lexer struct {\n\tlexerState\n\n\tinput string\n}\n\nfunc NewLexer(buf string) *Lexer {\n\treturn &Lexer{input: buf}\n}\n\nfunc (l *Lexer) saveState() lexerState {\n\treturn l.lexerState\n}\n\nfunc (l *Lexer) restoreState(state lexerState) {\n\tl.lexerState = state\n}\n\nfunc (l *Lexer) skipN(n int) {\n\tl.current += n\n}\n\nfunc (l *Lexer) slice(i, j int) string {\n\treturn l.input[l.current+i : l.current+j]\n}\n\nfunc (l *Lexer) peekN(n int) byte {\n\treturn l.input[l.current+n]\n}\n\nfunc (l *Lexer) peekOk(n int) bool {\n\treturn l.current+n < len(l.input)\n}\n\nfunc (l *Lexer) isKeyword(ident string) bool {\n\treturn keywords.Contains(ident)\n}\n\nfunc (l *Lexer) consumeNumber() error {\n\ti := 0\n\tbase := 10\n\tif l.peekN(0) == '+' || l.peekN(0) == '-' {\n\t\t// skip sign\n\t\ti++\n\t}\n\tif l.peekN(0) == '0' && l.peekOk(1) && l.peekN(1) == 'x' {\n\t\ti += 2\n\t\tbase = 16\n\t}\n\n\thasExp := false\n\ttokenKind := TokenKindInt\n\thasNumberPart := false\n\tfor l.peekOk(i) {\n\t\thasNumberPart = true\n\t\tc := l.peekN(i)\n\t\tswitch {\n\t\tcase base == 10 && IsDigit(c):\n\t\t\ti++\n\t\t\tcontinue\n\t\tcase base == 16 && IsHexDigit(c):\n\t\t\ti++\n\t\t\tcontinue\n\t\tcase c == '.': // float\n\t\t\ttokenKind = TokenKindFloat\n\t\t\ti++\n\t\t\tcontinue\n\t\tcase base != 16 && (c == 'e' || c == 'E' || c == 'p' || c == 'P'):\n\t\t\tif hasExp {\n\t\t\t\treturn errors.New(\"invalid number\")\n\t\t\t}\n\t\t\ti++\n\t\t\tif l.peekOk(i) && (l.peekN(i) == '+' || l.peekN(i) == '-') {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif !l.peekOk(i) || !IsDigit(l.peekN(i)) {\n\t\t\t\treturn errors.New(\"exponent part should contain at least one digit\")\n\t\t\t}\n\t\t\thasExp = true\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\tif (l.peekOk(i) && IsIdentPart(l.peekN(i))) || !hasNumberPart {\n\t\treturn errors.New(\"invalid number\")\n\t}\n\tl.lastToken = &Token{\n\t\tKind:   tokenKind,\n\t\tString: l.slice(0, i),\n\t\tPos:    Pos(l.current),\n\t\tEnd:    Pos(l.current + i),\n\t\tBase:   base,\n\t}\n\tl.skipN(i)\n\treturn nil\n}\n\nfunc (l *Lexer) consumeIdent(_ Pos) error {\n\ttoken := &Token{}\n\tquoteType := Unquoted\n\tif l.peekOk(0) && (l.peekN(0) == '`' || l.peekN(0) == '\"') {\n\t\tif l.peekOk(0) && l.peekN(0) == '`' {\n\t\t\tquoteType = BackTicks\n\t\t} else {\n\t\t\tquoteType = DoubleQuote\n\t\t}\n\t\tl.skipN(1)\n\t}\n\n\ti := 0\n\tif quoteType == Unquoted {\n\t\tif l.peekOk(i) && l.peekN(i) == '$' {\n\t\t\ti++\n\t\t}\n\t\tfor l.peekOk(i) && IsIdentPart(l.peekN(i)) {\n\t\t\ti++\n\t\t}\n\t} else {\n\t\tfor l.peekOk(i) && (quoteType == BackTicks && l.peekN(i) != '`' ||\n\t\t\tquoteType == DoubleQuote && l.peekN(i) != '\"') {\n\t\t\ti++\n\t\t}\n\t\tif !l.peekOk(i) || (quoteType == BackTicks && l.peekN(i) != '`') ||\n\t\t\t(quoteType == DoubleQuote && l.peekN(i) != '\"') {\n\t\t\treturn fmt.Errorf(\"unclosed quoted identifier: %s\", l.slice(0, i))\n\t\t}\n\t}\n\tslice := l.slice(0, i)\n\tif quoteType == Unquoted && l.isKeyword(strings.ToUpper(slice)) {\n\t\ttoken.Kind = TokenKindKeyword\n\t} else {\n\t\ttoken.Kind = TokenKindIdent\n\t}\n\ttoken.Pos = Pos(l.current)\n\ttoken.End = Pos(l.current + i)\n\ttoken.String = slice\n\ttoken.QuoteType = quoteType\n\tl.lastToken = token\n\n\tl.skipN(i)\n\tif quoteType != Unquoted {\n\t\tl.skipN(1)\n\t}\n\treturn nil\n}\n\nfunc (l *Lexer) consumeSingleLineComment() {\n\tl.skipN(2)\n\ti := 0\n\tfor l.peekOk(i) && l.peekN(i) != '\\r' && l.peekN(i) != '\\n' {\n\t\ti++\n\t}\n\tl.skipN(i + 1)\n}\n\nfunc (l *Lexer) consumeMultiLineComment() {\n\tl.skipN(2)\n\ti := 0\n\tfor !l.isEOF() {\n\t\tif l.peekOk(i+1) && l.peekN(i) == '*' && l.peekN(i+1) == '/' {\n\t\t\ti += 2\n\t\t\tbreak\n\t\t}\n\t\ti++\n\t}\n\tl.skipN(i)\n}\n\nfunc (l *Lexer) consumeString() error {\n\ti := 1\n\tendChar := byte('\\'')\n\tfor l.peekOk(i) {\n\t\tc := l.peekN(i)\n\t\t// backslash escape\n\t\tif c == '\\\\' {\n\t\t\ti++\n\t\t\tif l.peekOk(i) {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\t// single quote\n\t\tif c == endChar {\n\t\t\t// double single quote ''\n\t\t\tif l.peekOk(i+1) && l.peekN(i+1) == endChar {\n\t\t\t\ti += 2\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\ti++\n\t}\n\tif !l.peekOk(i) || l.peekN(i) != endChar {\n\t\treturn errors.New(\"invalid string\")\n\t}\n\tl.lastToken = &Token{\n\t\tKind:   TokenKindString,\n\t\tString: l.slice(1, i),\n\t\tPos:    Pos(l.current + 1),\n\t\tEnd:    Pos(l.current + i),\n\t}\n\tl.skipN(i + 1)\n\treturn nil\n}\n\nfunc (l *Lexer) skipComments() {\n\tfor !l.isEOF() {\n\t\tl.skipSpace()\n\t\tif !l.peekOk(0) {\n\t\t\treturn\n\t\t}\n\t\tswitch l.peekN(0) {\n\t\tcase '-':\n\t\t\tif l.peekOk(1) && l.peekN(1) == '-' {\n\t\t\t\tl.consumeSingleLineComment()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn\n\t\tcase '/': // multi-line comment\n\t\t\tif l.peekOk(1) && l.peekN(1) == '*' {\n\t\t\t\tl.consumeMultiLineComment()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn\n\t\tcase '\\r', '\\n':\n\t\t\t// skip \\r\\n or \\n\\r\n\t\t\tl.skipN(1)\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (l *Lexer) peekToken() (*Token, error) {\n\tsavedState := l.saveState()\n\tif err := l.consumeToken(); err != nil {\n\t\treturn nil, err\n\t}\n\ttoken := l.lastToken\n\n\tl.restoreState(savedState)\n\treturn token, nil\n}\n\nfunc (l *Lexer) hasPrecedenceToken(last *Token) bool {\n\treturn last != nil && (last.Kind == TokenKindIdent ||\n\t\tlast.Kind == TokenKindKeyword ||\n\t\tlast.Kind == TokenKindInt ||\n\t\tlast.Kind == TokenKindFloat ||\n\t\tlast.Kind == TokenKindString)\n}\n\nfunc (l *Lexer) consumeToken() error {\n\t// clear last token\n\tlastToken := l.lastToken\n\tl.lastToken = nil\n\tl.skipComments()\n\tl.skipSpace()\n\tif l.isEOF() {\n\t\treturn nil\n\t}\n\tswitch l.peekN(0) {\n\tcase '>', '<', '!', '=', '|':\n\t\tif l.peekN(0) == '|' && l.peekOk(1) && l.peekN(1) == '|' || // ||\n\t\t\tl.peekN(0) == '<' && l.peekOk(1) && l.peekN(1) == '>' || // <>\n\t\t\tl.peekN(0) == '=' && l.peekOk(1) && l.peekN(1) == '=' || // ==\n\t\t\tl.peekN(0) != '|' && l.peekOk(1) && l.peekN(1) == '=' { // |=\n\t\t\tl.lastToken = &Token{\n\t\t\t\tString: l.slice(0, 2),\n\t\t\t\tKind:   TokenKind(l.slice(0, 2)),\n\t\t\t\tPos:    Pos(l.current),\n\t\t\t\tEnd:    Pos(l.current + 2),\n\t\t\t}\n\t\t\tl.skipN(2)\n\t\t\treturn nil\n\t\t}\n\n\tcase '+', '-':\n\t\t// hasPrecedenceToken is used to distinguish between unary and binary operators\n\t\tif !l.hasPrecedenceToken(lastToken) && l.peekOk(1) && IsDigit(l.peekN(1)) {\n\t\t\treturn l.consumeNumber()\n\t\t} else if l.peekOk(1) && l.peekN(1) == '>' {\n\t\t\tl.lastToken = &Token{\n\t\t\t\tString: l.slice(0, 2),\n\t\t\t\tKind:   TokenKindArrow,\n\t\t\t\tPos:    Pos(l.current),\n\t\t\t\tEnd:    Pos(l.current + 2),\n\t\t\t}\n\t\t\tl.skipN(2)\n\t\t\treturn nil\n\t\t}\n\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\treturn l.consumeNumber()\n\tcase '`', '$', '\"':\n\t\treturn l.consumeIdent(Pos(l.current))\n\tcase '\\'':\n\t\treturn l.consumeString()\n\tcase ':':\n\t\tif l.peekOk(1) && l.peekN(1) == ':' {\n\t\t\tl.lastToken = &Token{\n\t\t\t\tString: l.slice(0, 2),\n\t\t\t\tKind:   TokenKindDash,\n\t\t\t\tPos:    Pos(l.current),\n\t\t\t\tEnd:    Pos(l.current + 2),\n\t\t\t}\n\t\t\tl.skipN(2)\n\t\t\treturn nil\n\t\t}\n\tcase '.':\n\t\tl.lastToken = &Token{\n\t\t\tString: l.slice(0, 1),\n\t\t\tKind:   TokenKindDot,\n\t\t\tPos:    Pos(l.current),\n\t\t\tEnd:    Pos(l.current + 1),\n\t\t}\n\t\tl.skipN(1)\n\t\treturn nil\n\t}\n\n\tif IsIdentStart(l.peekN(0)) {\n\t\treturn l.consumeIdent(Pos(l.current))\n\t}\n\n\ttoken := &Token{}\n\ttoken.Pos = Pos(l.current)\n\ttoken.End = Pos(l.current + 1)\n\ttoken.String = l.input[l.current : l.current+1]\n\ttoken.Kind = TokenKind(token.String)\n\tl.skipN(1)\n\tl.lastToken = token\n\treturn nil\n}\n\nfunc (l *Lexer) isEOF() bool {\n\treturn l.current >= len(l.input)\n}\n\nfunc (l *Lexer) skipSpace() {\n\tfor !l.isEOF() {\n\t\tr, size := utf8.DecodeRuneInString(l.input[l.current:])\n\t\tif !unicode.IsSpace(r) {\n\t\t\tbreak\n\t\t}\n\t\tl.current += size\n\t}\n}\n"
  },
  {
    "path": "parser/lexer_test.go",
    "content": "package parser\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestConsumeComment(t *testing.T) {\n\tcomments := []string{\n\t\t\"-- hello world\",\n\t\t\"-- hello world\\n\",\n\t\t\"-- hello world\\r\\n\",\n\t\t\"-- hello world\\r\",\n\t\t\"/* hello world */\",\n\t\t\"/* hello world */\\n\",\n\t\t\"/* hello world */\\r\\n\",\n\t\t\"/* hello world */\\r\",\n\t\t\"/* hello world */ /* hello world */\",\n\t\t\"/* hello world */ /* hello world */\\n\",\n\t\t\"/* hello world */ /* hello world */\\r\\n\",\n\t\t\"/* hello world */ /* hello world */\\r\",\n\t}\n\tfor _, c := range comments {\n\t\tlexer := NewLexer(c)\n\t\terr := lexer.consumeToken()\n\t\trequire.NoError(t, err)\n\t}\n\n}\n\nfunc TestConsumeString(t *testing.T) {\n\tt.Run(\"Simple strings\", func(t *testing.T) {\n\t\tstrs := []string{\n\t\t\t\"'hello world'\",\n\t\t\t\"'123'\",\n\t\t}\n\t\tfor _, s := range strs {\n\t\t\tlexer := NewLexer(s)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, TokenKindString, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, strings.Trim(s, \"'\"), lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Strings with backslash-escaped quotes\", func(t *testing.T) {\n\t\ttestCases := []struct {\n\t\t\tinput    string\n\t\t\texpected string\n\t\t}{\n\t\t\t{`'hello\\'world'`, `hello\\'world`},\n\t\t\t{`'test\\''`, `test\\'`},\n\t\t\t{`'\\'abc\\''`, `\\'abc\\'`},\n\t\t}\n\t\tfor _, tc := range testCases {\n\t\t\tlexer := NewLexer(tc.input)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err, \"Failed to parse: %s\", tc.input)\n\t\t\trequire.Equal(t, TokenKindString, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, tc.expected, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Strings with double single quotes\", func(t *testing.T) {\n\t\ttestCases := []struct {\n\t\t\tinput    string\n\t\t\texpected string\n\t\t}{\n\t\t\t{`'hello''world'`, `hello''world`},\n\t\t\t{`'test''123'`, `test''123`},\n\t\t\t{`'abc''def''ghi'`, `abc''def''ghi`},\n\t\t}\n\t\tfor _, tc := range testCases {\n\t\t\tlexer := NewLexer(tc.input)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err, \"Failed to parse: %s\", tc.input)\n\t\t\trequire.Equal(t, TokenKindString, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, tc.expected, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Strings with backslash-escaped backslashes\", func(t *testing.T) {\n\t\ttestCases := []struct {\n\t\t\tinput    string\n\t\t\texpected string\n\t\t}{\n\t\t\t{`'a\\\\b'`, `a\\\\b`},\n\t\t\t{`'test\\\\123'`, `test\\\\123`},\n\t\t}\n\t\tfor _, tc := range testCases {\n\t\t\tlexer := NewLexer(tc.input)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err, \"Failed to parse: %s\", tc.input)\n\t\t\trequire.Equal(t, TokenKindString, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, tc.expected, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n}\n\nfunc TestConsumeNumber(t *testing.T) {\n\tt.Run(\"Integer number\", func(t *testing.T) {\n\t\tintegers := []string{\n\t\t\t\"123\",\n\t\t\t\"123e+10\",\n\t\t\t\"123e-10\",\n\t\t\t\"123e10\",\n\t\t\t\"123E10\",\n\t\t\t\"123E+10\",\n\t\t\t\"123E-10\",\n\t\t}\n\t\tfor _, i := range integers {\n\t\t\tlexer := NewLexer(i)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, TokenKindInt, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, 10, lexer.lastToken.Base)\n\t\t\trequire.Equal(t, i, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Hexadecimal number\", func(t *testing.T) {\n\t\tnumbers := []string{\n\t\t\t\"0x123\",\n\t\t\t\"0x1\",\n\t\t}\n\t\tfor _, n := range numbers {\n\t\t\tlexer := NewLexer(n)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, TokenKindInt, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, 16, lexer.lastToken.Base)\n\t\t\trequire.Equal(t, n, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Invalid number\", func(t *testing.T) {\n\t\tinvalidNumbers := []string{\n\t\t\t\"123e\",\n\t\t\t\"123e+\",\n\t\t\t\"123e-\",\n\t\t\t\"123e\",\n\t\t\t\"123E\",\n\t\t\t\"123E+\",\n\t\t\t\"123E-\",\n\t\t\t\"0x\",\n\t\t\t\"0xg\",\n\t\t}\n\t\tfor _, n := range invalidNumbers {\n\t\t\tlexer := NewLexer(n)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.Error(t, err)\n\t\t}\n\t})\n\n\tt.Run(\"Float number\", func(t *testing.T) {\n\t\tfloats := []string{\n\t\t\t\"123.456\",\n\t\t\t\"123.456e+10\",\n\t\t\t\"123.456e-10\",\n\t\t\t\"123.456e10\",\n\t\t\t\"123.456E10\",\n\t\t\t\"123.456E+10\",\n\t\t\t\"123.456E-10\",\n\t\t}\n\t\tfor _, f := range floats {\n\t\t\tlexer := NewLexer(f)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, TokenKindFloat, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, f, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Invalid float number\", func(t *testing.T) {\n\t\tinvalidFloats := []string{\n\t\t\t\"123.456b\",\n\t\t\t\"123.456e\",\n\t\t\t\"123.456e+\",\n\t\t\t\"123.456e-\",\n\t\t\t\"123.456e+10e\",\n\t\t\t\"123.456e-10e\",\n\t\t\t\"123.456e10e\",\n\t\t\t\"123.456E10e\",\n\t\t\t\"123.456E+10e\",\n\t\t\t\"123.456E-10e\",\n\t\t\t\"123.456e+10e+10\",\n\t\t}\n\t\tfor _, f := range invalidFloats {\n\t\t\tlexer := NewLexer(f)\n\t\t\terr := lexer.consumeToken()\n\t\t\tassert.Error(t, err)\n\t\t}\n\t})\n\n\tt.Run(\"Name\", func(t *testing.T) {\n\t\tidents := []string{\n\t\t\t\"`CASE`\",\n\t\t\t\"`TEST`\",\n\t\t\t\"`WHEN`\",\n\t\t\t\"hello\",\n\t\t\t\"hello_world\",\n\t\t\t\"hello123\",\n\t\t\t\"hello_123\",\n\t\t\t\"hello_123_world\",\n\t\t\t\"hello_123_world_456\",\n\t\t\t\"hello_123_world_456_789\",\n\t\t\t\"hello_123_world_456_789_abc\",\n\t\t\t\"hello_123_world_456_789_abc_def\",\n\t\t\t\"hello_123_world_456_789_abc_def_ghi\",\n\t\t\t\"hello_123_world_456_789_abc_def_ghi_jkl\",\n\t\t\t\"hello_123_world_456_789_abc_def_ghi_jkl_mno\",\n\t\t\t\"hello_123_world_456_789_abc_def_ghi_jkl_mno_pqr\",\n\t\t}\n\t\tfor _, i := range idents {\n\t\t\tlexer := NewLexer(i)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, TokenKindIdent, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, strings.Trim(i, \"`\"), lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n\n\tt.Run(\"Keyword\", func(t *testing.T) {\n\t\tfor _, k := range keywords.Members() {\n\t\t\tlexer := NewLexer(k)\n\t\t\terr := lexer.consumeToken()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, TokenKindKeyword, lexer.lastToken.Kind)\n\t\t\trequire.Equal(t, k, lexer.lastToken.String)\n\t\t\trequire.True(t, lexer.isEOF())\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "parser/parse_system.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc (p *Parser) parseSetStmt(pos Pos) (*SetStmt, error) {\n\tif err := p.expectKeyword(KeywordSet); err != nil {\n\t\treturn nil, err\n\t}\n\tsettings, err := p.parseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SetStmt{\n\t\tSetPos:   pos,\n\t\tSettings: settings,\n\t}, nil\n}\n\nfunc (p *Parser) parseSettingsStmt(pos Pos) (*SetStmt, error) {\n\tif err := p.expectKeyword(KeywordSettings); err != nil {\n\t\treturn nil, err\n\t}\n\tsettings, err := p.parseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SetStmt{\n\t\tSetPos:   pos,\n\t\tSettings: settings,\n\t}, nil\n}\n\nfunc (p *Parser) parseSystemFlushExpr(pos Pos) (*SystemFlushExpr, error) {\n\tif err := p.expectKeyword(KeywordFlush); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch {\n\tcase p.matchKeyword(KeywordLogs):\n\t\tlastToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &SystemFlushExpr{\n\t\t\tFlushPos:     pos,\n\t\t\tStatementEnd: lastToken.End,\n\t\t\tLogs:         true,\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordDistributed):\n\t\tdistributed, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &SystemFlushExpr{\n\t\t\tFlushPos:     pos,\n\t\t\tStatementEnd: distributed.End(),\n\t\t\tDistributed:  distributed,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected LOGS|DISTRIBUTED\")\n\t}\n}\n\nfunc (p *Parser) parseSystemReloadExpr(pos Pos) (*SystemReloadExpr, error) {\n\tif err := p.expectKeyword(KeywordReload); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch {\n\tcase p.matchKeyword(KeywordDictionaries):\n\t\tlastToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &SystemReloadExpr{\n\t\t\tReloadPos:    pos,\n\t\t\tStatementEnd: lastToken.End,\n\t\t\tType:         KeywordDictionaries,\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordDictionary):\n\t\tdictionary, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &SystemReloadExpr{\n\t\t\tReloadPos:    pos,\n\t\t\tStatementEnd: dictionary.End(),\n\t\t\tType:         KeywordDictionary,\n\t\t\tDictionary:   dictionary,\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordEmbedded):\n\t\tlastToken := p.last()\n\t\tif err := p.expectKeyword(KeywordDictionaries); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &SystemReloadExpr{\n\t\t\tReloadPos:    pos,\n\t\t\tStatementEnd: lastToken.End,\n\t\t\tType:         \"EMBEDDED DICTIONARIES\",\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected DICTIONARIES|CONFIG\")\n\t}\n}\n\nfunc (p *Parser) parseSystemSyncExpr(pos Pos) (*SystemSyncExpr, error) {\n\tif err := p.expectKeyword(KeywordSync); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordReplica); err != nil {\n\t\treturn nil, err\n\t}\n\tcluster, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SystemSyncExpr{\n\t\tSyncPos: pos,\n\t\tCluster: cluster,\n\t}, nil\n}\n\nfunc (p *Parser) parseSystemCtrlExpr(pos Pos) (*SystemCtrlExpr, error) {\n\tif !p.matchKeyword(KeywordStart) && !p.matchKeyword(KeywordStop) {\n\t\treturn nil, fmt.Errorf(\"expected START|STOP\")\n\t}\n\tcommand := strings.ToUpper(p.last().String)\n\t_ = p.lexer.consumeToken()\n\n\tvar typ string\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordDistributed):\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordSends):\n\t\t\ttyp = \"DISTRIBUTED SENDS\"\n\t\tcase p.matchKeyword(KeywordFetches):\n\t\t\ttyp = \"FETCHES\"\n\t\tcase p.matchKeyword(KeywordMerges):\n\t\t\ttyp = \"MERGES\"\n\t\tcase p.matchKeyword(KeywordTtl):\n\t\t\ttyp = \"TTL MERGES\"\n\t\t\tif err := p.expectKeyword(KeywordMerges); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected SENDS|FETCHES|MERGES|TTL\")\n\t\t}\n\t\tcluster, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &SystemCtrlExpr{\n\t\t\tCtrlPos:      pos,\n\t\t\tStatementEnd: cluster.End(),\n\t\t\tCommand:      command,\n\t\t\tType:         typ,\n\t\t\tCluster:      cluster,\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordReplicated):\n\t\tlastToken := p.last()\n\t\tif err := p.expectKeyword(KeywordSends); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttyp = \"REPLICATED SENDS\"\n\t\treturn &SystemCtrlExpr{\n\t\t\tCtrlPos:      pos,\n\t\t\tStatementEnd: lastToken.End,\n\t\t\tCommand:      command,\n\t\t\tType:         typ,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected DISTRIBUTED|REPLICATED\")\n\t}\n}\n\nfunc (p *Parser) parseSystemDropExpr(pos Pos) (*SystemDropExpr, error) {\n\tif err := p.expectKeyword(KeywordDrop); err != nil {\n\t\treturn nil, err\n\t}\n\tswitch {\n\tcase p.matchKeyword(KeywordDNS),\n\t\tp.matchKeyword(KeywordMark),\n\t\tp.matchKeyword(KeywordUncompressed),\n\t\tp.matchKeyword(KeywordFileSystem),\n\t\tp.matchKeyword(KeywordQuery):\n\t\tprefixToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\tlastToken := p.last()\n\t\tif err := p.expectKeyword(KeywordCache); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &SystemDropExpr{\n\t\t\tDropPos:      pos,\n\t\t\tStatementEnd: lastToken.End,\n\t\t\tType:         prefixToken.String + \" CACHE\",\n\t\t}, nil\n\tcase p.matchKeyword(KeywordCompiled):\n\t\t_ = p.lexer.consumeToken()\n\t\tif err := p.expectKeyword(KeywordExpression); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlastToken := p.last()\n\t\tif err := p.expectKeyword(KeywordCache); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &SystemDropExpr{\n\t\t\tDropPos:      pos,\n\t\t\tStatementEnd: lastToken.End,\n\t\t\tType:         \"COMPILED EXPRESSION CACHE\",\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected DNS|MARK|REPLICA|DATABASE|UNCOMPRESSION|COMPILED|QUERY\")\n\t}\n}\n\nfunc (p *Parser) tryParseDeduplicateClause(pos Pos) (*DeduplicateClause, error) {\n\tif !p.matchKeyword(KeywordDeduplicate) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseDeduplicateClause(pos)\n}\n\nfunc (p *Parser) parseDeduplicateClause(pos Pos) (*DeduplicateClause, error) {\n\tif err := p.expectKeyword(KeywordDeduplicate); err != nil {\n\t\treturn nil, err\n\t}\n\tif !p.tryConsumeKeywords(KeywordBy) {\n\t\treturn &DeduplicateClause{\n\t\t\tDeduplicatePos: pos,\n\t\t}, nil\n\t}\n\n\tby, err := p.parseColumnExprList(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar except *ColumnExprList\n\tif p.tryConsumeKeywords(KeywordExcept) {\n\t\texcept, err = p.parseColumnExprList(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn &DeduplicateClause{\n\t\tDeduplicatePos: pos,\n\t\tBy:             by,\n\t\tExcept:         except,\n\t}, nil\n}\n\nfunc (p *Parser) parseOptimizeStmt(pos Pos) (*OptimizeStmt, error) {\n\tif err := p.expectKeyword(KeywordOptimize); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\treturn nil, err\n\t}\n\n\ttable, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatementEnd := table.End()\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif onCluster != nil {\n\t\tstatementEnd = onCluster.End()\n\t}\n\n\tpartition, err := p.tryParsePartitionClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif partition != nil {\n\t\tstatementEnd = partition.End()\n\t}\n\n\thasFinal := false\n\tlastPos := p.Pos()\n\tif p.tryConsumeKeywords(KeywordFinal) {\n\t\thasFinal = true\n\t\tstatementEnd = lastPos\n\t}\n\n\tdeduplicate, err := p.tryParseDeduplicateClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif deduplicate != nil {\n\t\tstatementEnd = deduplicate.End()\n\t}\n\n\treturn &OptimizeStmt{\n\t\tOptimizePos:  pos,\n\t\tStatementEnd: statementEnd,\n\t\tTable:        table,\n\t\tOnCluster:    onCluster,\n\t\tPartition:    partition,\n\t\tHasFinal:     hasFinal,\n\t\tDeduplicate:  deduplicate,\n\t}, nil\n}\n\nfunc (p *Parser) parseSystemStmt(pos Pos) (*SystemStmt, error) {\n\tif err := p.expectKeyword(KeywordSystem); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar err error\n\tvar expr Expr\n\tswitch {\n\tcase p.matchKeyword(KeywordFlush):\n\t\texpr, err = p.parseSystemFlushExpr(p.Pos())\n\tcase p.matchKeyword(KeywordReload):\n\t\texpr, err = p.parseSystemReloadExpr(p.Pos())\n\tcase p.matchKeyword(KeywordSync):\n\t\texpr, err = p.parseSystemSyncExpr(p.Pos())\n\tcase p.matchKeyword(KeywordStart), p.matchKeyword(KeywordStop):\n\t\texpr, err = p.parseSystemCtrlExpr(p.Pos())\n\tcase p.matchKeyword(KeywordDrop):\n\t\texpr, err = p.parseSystemDropExpr(p.Pos())\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected FLUSH|RELOAD|SYNC|START|STOP\")\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SystemStmt{\n\t\tSystemPos: pos,\n\t\tExpr:      expr,\n\t}, nil\n}\n\nfunc (p *Parser) parseCheckStmt(pos Pos) (*CheckStmt, error) {\n\tif err := p.expectKeyword(KeywordCheck); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\treturn nil, err\n\t}\n\ttable, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpartition, err := p.tryParsePartitionClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &CheckStmt{\n\t\tCheckPos:  pos,\n\t\tTable:     table,\n\t\tPartition: partition,\n\t}, nil\n}\n\nfunc (p *Parser) parseRoleName(_ Pos) (*RoleName, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\tname, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar scope *StringLiteral\n\t\tif p.tryConsumeTokenKind(TokenKindAtSign) != nil {\n\t\t\tscope, err = p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &RoleName{\n\t\t\tName:      name,\n\t\t\tScope:     scope,\n\t\t\tOnCluster: onCluster,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindString):\n\t\tname, err := p.parseString(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &RoleName{\n\t\t\tName:      name,\n\t\t\tOnCluster: onCluster,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected <ident> or <string>\")\n\t}\n}\n\nfunc (p *Parser) tryParseRoleSettings(pos Pos) ([]*RoleSetting, error) {\n\tif !p.tryConsumeKeywords(KeywordSettings) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseRoleSettings(pos)\n}\n\nfunc (p *Parser) parseRoleSetting(_ Pos) (*RoleSetting, error) {\n\tpairs := make([]*SettingPair, 0)\n\tfor p.matchTokenKind(TokenKindIdent) {\n\t\tname, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch name.Name {\n\t\tcase \"NONE\", \"READABLE\", \"WRITABLE\", \"CONST\", \"CHANGEABLE_IN_READONLY\":\n\t\t\treturn &RoleSetting{\n\t\t\t\tModifier:     name,\n\t\t\t\tSettingPairs: pairs,\n\t\t\t}, nil\n\t\t}\n\t\tswitch {\n\t\tcase p.matchTokenKind(TokenKindSingleEQ),\n\t\t\tp.matchTokenKind(TokenKindInt),\n\t\t\tp.matchTokenKind(TokenKindFloat),\n\t\t\tp.matchTokenKind(TokenKindString):\n\t\t\tvar op TokenKind\n\t\t\tif token := p.tryConsumeTokenKind(TokenKindSingleEQ); token != nil {\n\t\t\t\top = token.Kind\n\t\t\t}\n\t\t\tvalue, err := p.parseLiteral(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// docs: https://clickhouse.com/docs/en/sql-reference/statements/alter/role\n\t\t\t// the operator \"=\" was required if the variable name is NOT in\n\t\t\t// [\"MIN\", \"MAX\", \"PROFILE\"] and value is existed.\n\t\t\tif value != nil && name.Name != \"MIN\" && name.Name != \"MAX\" && name.Name != \"PROFILE\" && op != TokenKindSingleEQ {\n\t\t\t\treturn nil, fmt.Errorf(\"expected operator = or no value, but got %s\", op)\n\t\t\t}\n\t\t\tpairs = append(pairs, &SettingPair{\n\t\t\t\tName:      name,\n\t\t\t\tOperation: op,\n\t\t\t\tValue:     value,\n\t\t\t})\n\t\tdefault:\n\t\t\tpairs = append(pairs, &SettingPair{\n\t\t\t\tName: name,\n\t\t\t})\n\t\t}\n\n\t}\n\treturn &RoleSetting{\n\t\tSettingPairs: pairs,\n\t}, nil\n}\n\nfunc (p *Parser) parseRoleSettings(_ Pos) ([]*RoleSetting, error) {\n\tsettings := make([]*RoleSetting, 0)\n\tfor {\n\t\tsetting, err := p.parseRoleSetting(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsettings = append(settings, setting)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn settings, nil\n}\n\nfunc (p *Parser) parseCreateRole(pos Pos) (*CreateRole, error) {\n\tif err := p.expectKeyword(KeywordRole); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifNotExists := false\n\torReplace := false\n\tswitch {\n\tcase p.matchKeyword(KeywordIf):\n\t\t_ = p.lexer.consumeToken()\n\t\tif err := p.expectKeyword(KeywordNot); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := p.expectKeyword(KeywordExists); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tifNotExists = true\n\tcase p.matchKeyword(KeywordOr):\n\t\t_ = p.lexer.consumeToken()\n\t\tif err := p.expectKeyword(KeywordReplace); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\torReplace = true\n\t}\n\n\troleNames := make([]*RoleName, 0)\n\troleName, err := p.parseRoleName(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troleNames = append(roleNames, roleName)\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\troleName, err := p.parseRoleName(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troleNames = append(roleNames, roleName)\n\t}\n\tstatementEnd := roleNames[len(roleNames)-1].End()\n\n\tvar accessStorageType *Ident\n\tif p.tryConsumeKeywords(KeywordIn) {\n\t\taccessStorageType, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstatementEnd = accessStorageType.NameEnd\n\t}\n\n\tsettings, err := p.tryParseRoleSettings(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif settings != nil {\n\t\tstatementEnd = settings[len(settings)-1].End()\n\t}\n\n\treturn &CreateRole{\n\t\tCreatePos:         pos,\n\t\tStatementEnd:      statementEnd,\n\t\tIfNotExists:       ifNotExists,\n\t\tOrReplace:         orReplace,\n\t\tRoleNames:         roleNames,\n\t\tAccessStorageType: accessStorageType,\n\t\tSettings:          settings,\n\t}, nil\n}\n\nfunc (p *Parser) parseAuthenticationClause(pos Pos) (*AuthenticationClause, error) {\n\tauth := &AuthenticationClause{AuthPos: pos}\n\n\tif p.tryConsumeKeywords(KeywordNot) {\n\t\tif err := p.expectKeyword(KeywordIdentified); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tauth.NotIdentified = true\n\t\tauth.AuthEnd = p.last().End\n\t\treturn auth, nil\n\t}\n\n\tif err := p.expectKeyword(KeywordIdentified); err != nil {\n\t\treturn nil, err\n\t}\n\tauth.AuthEnd = p.last().End\n\n\tif p.tryConsumeKeywords(KeywordWith) {\n\t\tif p.matchKeyword(KeywordLdap) {\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tif err := p.expectKeyword(KeywordServer); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tserver, err := p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tauth.LdapServer = server\n\t\t\tauth.AuthEnd = server.End()\n\t\t} else if p.matchKeyword(KeywordKerberos) {\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tauth.IsKerberos = true\n\t\t\tauth.AuthEnd = p.last().End\n\t\t\tif p.tryConsumeKeywords(KeywordRealm) {\n\t\t\t\trealm, err := p.parseString(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tauth.KerberosRealm = realm\n\t\t\t\tauth.AuthEnd = realm.End()\n\t\t\t}\n\t\t} else if p.matchTokenKind(TokenKindIdent) {\n\t\t\t// Auth types like no_password, plaintext_password, etc.\n\t\t\tauthType := p.last().String\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tauth.AuthType = authType\n\t\t\tauth.AuthEnd = p.last().End\n\n\t\t\tif p.tryConsumeKeywords(KeywordBy) {\n\t\t\t\tvalue, err := p.parseString(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tauth.AuthValue = value\n\t\t\t\tauth.AuthEnd = value.End()\n\t\t\t}\n\t\t}\n\t}\n\n\treturn auth, nil\n}\n\nfunc (p *Parser) parseHostClause(pos Pos) (*HostClause, error) {\n\tif err := p.expectKeyword(KeywordHost); err != nil {\n\t\treturn nil, err\n\t}\n\n\thost := &HostClause{HostPos: pos}\n\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordLocal, KeywordAny, KeywordNone):\n\t\thostType := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\thost.HostType = hostType\n\t\thost.HostEnd = p.last().End\n\tcase p.matchOneOfKeywords(KeywordName, KeywordRegexp, KeywordIp, KeywordLike):\n\t\thostType := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\thost.HostType = hostType\n\t\tvalue, err := p.parseString(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thost.HostValue = value\n\t\thost.HostEnd = value.End()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected LOCAL|NAME|REGEXP|IP|LIKE|ANY|NONE\")\n\t}\n\n\treturn host, nil\n}\n\nfunc (p *Parser) parseDefaultRoleClause(pos Pos) (*DefaultRoleClause, error) {\n\tif err := p.expectKeyword(KeywordDefault); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordRole); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefaultRole := &DefaultRoleClause{DefaultPos: pos}\n\n\tif p.tryConsumeKeywords(KeywordNone) {\n\t\tdefaultRole.None = true\n\t\tdefaultRole.DefaultEnd = p.last().End\n\t\treturn defaultRole, nil\n\t}\n\n\troles := make([]*RoleName, 0)\n\trole, err := p.parseRoleName(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troles = append(roles, role)\n\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\trole, err := p.parseRoleName(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troles = append(roles, role)\n\t}\n\n\tdefaultRole.Roles = roles\n\tdefaultRole.DefaultEnd = roles[len(roles)-1].End()\n\treturn defaultRole, nil\n}\n\nfunc (p *Parser) parseGranteesClause(pos Pos) (*GranteesClause, error) {\n\tif err := p.expectKeyword(KeywordGrantees); err != nil {\n\t\treturn nil, err\n\t}\n\n\tgrantees := &GranteesClause{GranteesPos: pos}\n\n\tif p.tryConsumeKeywords(KeywordAny) {\n\t\tgrantees.Any = true\n\t\tgrantees.GranteesEnd = p.last().End\n\t} else if p.tryConsumeKeywords(KeywordNone) {\n\t\tgrantees.None = true\n\t\tgrantees.GranteesEnd = p.last().End\n\t} else {\n\t\t// Parse list of grantees\n\t\tgranteeList := make([]*RoleName, 0)\n\t\tgrantee, err := p.parseRoleName(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tgranteeList = append(granteeList, grantee)\n\n\t\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\t\tgrantee, err := p.parseRoleName(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tgranteeList = append(granteeList, grantee)\n\t\t}\n\n\t\tgrantees.Grantees = granteeList\n\t\tgrantees.GranteesEnd = granteeList[len(granteeList)-1].End()\n\t}\n\n\t// Check for EXCEPT clause\n\tif p.tryConsumeKeywords(KeywordExcept) {\n\t\texceptList := make([]*RoleName, 0)\n\t\texcept, err := p.parseRoleName(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texceptList = append(exceptList, except)\n\n\t\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\t\texcept, err := p.parseRoleName(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\texceptList = append(exceptList, except)\n\t\t}\n\n\t\tgrantees.ExceptUsers = exceptList\n\t\tgrantees.GranteesEnd = exceptList[len(exceptList)-1].End()\n\t}\n\n\treturn grantees, nil\n}\n\nfunc (p *Parser) parseCreateUserModifiers(createUser *CreateUser) error {\n\tswitch {\n\tcase p.matchKeyword(KeywordIf):\n\t\t_ = p.lexer.consumeToken()\n\t\tif err := p.expectKeyword(KeywordNot); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := p.expectKeyword(KeywordExists); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcreateUser.IfNotExists = true\n\tcase p.matchKeyword(KeywordOr):\n\t\t_ = p.lexer.consumeToken()\n\t\tif err := p.expectKeyword(KeywordReplace); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcreateUser.OrReplace = true\n\t}\n\treturn nil\n}\n\nfunc (p *Parser) parseUserNames() ([]*RoleName, error) {\n\tuserNames := make([]*RoleName, 0)\n\tuserName, err := p.parseRoleName(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tuserNames = append(userNames, userName)\n\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tuserName, err := p.parseRoleName(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tuserNames = append(userNames, userName)\n\t}\n\treturn userNames, nil\n}\n\nfunc (p *Parser) parseHostClauses() ([]*HostClause, error) {\n\thosts := make([]*HostClause, 0)\n\thost, err := p.parseHostClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\thosts = append(hosts, host)\n\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\thost, err := p.parseHostClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thosts = append(hosts, host)\n\t}\n\treturn hosts, nil\n}\n\nfunc (p *Parser) parseDefaultClause(createUser *CreateUser) (bool, error) {\n\tnextToken, err := p.lexer.peekToken()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif nextToken.String == KeywordRole {\n\t\tdefaultRole, err := p.parseDefaultRoleClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tcreateUser.DefaultRole = defaultRole\n\t\tcreateUser.StatementEnd = defaultRole.End()\n\t\treturn true, nil\n\t} else if nextToken.String == KeywordDatabase {\n\t\t_ = p.lexer.consumeToken() // consume DEFAULT\n\t\t_ = p.lexer.consumeToken() // consume DATABASE\n\t\tif p.tryConsumeKeywords(KeywordNone) {\n\t\t\tcreateUser.DefaultDbNone = true\n\t\t\tcreateUser.StatementEnd = p.last().End\n\t\t} else {\n\t\t\tdb, err := p.parseIdent()\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tcreateUser.DefaultDatabase = db\n\t\t\tcreateUser.StatementEnd = db.End()\n\t\t}\n\t\treturn true, nil\n\t}\n\treturn false, nil\n}\n\nfunc (p *Parser) parseOptionalClauses(createUser *CreateUser) error {\n\tcontinueParsing := true\n\tfor continueParsing {\n\t\tswitch {\n\t\tcase p.matchOneOfKeywords(KeywordNot, KeywordIdentified):\n\t\t\tauth, err := p.parseAuthenticationClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateUser.Authentication = auth\n\t\t\tcreateUser.StatementEnd = auth.End()\n\n\t\tcase p.matchKeyword(KeywordValid):\n\t\t\t_ = p.lexer.consumeToken() // consume VALID keyword\n\t\t\tif err := p.expectKeyword(KeywordUntil); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tvalidUntil, err := p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateUser.ValidUntil = validUntil\n\t\t\tcreateUser.StatementEnd = validUntil.End()\n\n\t\tcase p.matchKeyword(KeywordHost):\n\t\t\thosts, err := p.parseHostClauses()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateUser.Hosts = hosts\n\t\t\tcreateUser.StatementEnd = hosts[len(hosts)-1].End()\n\n\t\tcase p.matchKeyword(KeywordDefault):\n\t\t\tparsed, err := p.parseDefaultClause(createUser)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif !parsed {\n\t\t\t\tcontinueParsing = false\n\t\t\t}\n\n\t\tcase p.matchKeyword(KeywordGrantees):\n\t\t\tgrantees, err := p.parseGranteesClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateUser.Grantees = grantees\n\t\t\tcreateUser.StatementEnd = grantees.End()\n\n\t\tcase p.matchKeyword(KeywordSettings):\n\t\t\t_ = p.lexer.consumeToken() // consume SETTINGS keyword\n\t\t\tsettings, err := p.parseRoleSettings(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateUser.Settings = settings\n\t\t\tif len(settings) > 0 {\n\t\t\t\tcreateUser.StatementEnd = settings[len(settings)-1].End()\n\t\t\t}\n\n\t\tdefault:\n\t\t\tcontinueParsing = false\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (p *Parser) parseCreateUser(pos Pos) (*CreateUser, error) {\n\tif err := p.expectKeyword(KeywordUser); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreateUser := &CreateUser{CreatePos: pos}\n\n\t// Handle IF NOT EXISTS or OR REPLACE\n\tif err := p.parseCreateUserModifiers(createUser); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Parse user names\n\tuserNames, err := p.parseUserNames()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateUser.UserNames = userNames\n\tcreateUser.StatementEnd = userNames[len(userNames)-1].End()\n\n\t// Parse optional clauses\n\tif err := p.parseOptionalClauses(createUser); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn createUser, nil\n}\n\nfunc (p *Parser) parserDropUserOrRole(pos Pos) (*DropUserOrRole, error) {\n\tvar target string\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordUser, KeywordRole):\n\t\ttarget = p.last().String\n\t\t_ = p.lexer.consumeToken()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected USER|ROLE\")\n\t}\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnames := make([]*RoleName, 0)\n\tname, err := p.parseRoleName(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnames = append(names, name)\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tname, err := p.parseRoleName(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnames = append(names, name)\n\t}\n\tstatementEnd := names[len(names)-1].End()\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif onCluster != nil {\n\t\tstatementEnd = onCluster.End()\n\t}\n\n\tvar from *Ident\n\tif p.tryConsumeKeywords(KeywordFrom) {\n\t\tfrom, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tmodifier, err := p.tryParseModifier()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DropUserOrRole{\n\t\tDropPos:      pos,\n\t\tStatementEnd: statementEnd,\n\t\tTarget:       target,\n\t\tIfExists:     ifExists,\n\t\tNames:        names,\n\t\tFrom:         from,\n\t\tModifier:     modifier,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeSelectOrInsert(pos Pos) (*PrivilegeClause, error) {\n\tkeyword := p.last().String\n\t_ = p.lexer.consumeToken()\n\n\tvar err error\n\tvar params *ParamExprList\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\tparams, err = p.parseFunctionParams(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn &PrivilegeClause{\n\t\tPrivilegePos: pos,\n\t\tKeywords:     []string{keyword},\n\t\tParams:       params,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeAlter(pos Pos) (*PrivilegeClause, error) {\n\tkeywords := []string{KeywordAlter}\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordIndex):\n\t\tkeywords = append(keywords, KeywordIndex)\n\tcase p.matchOneOfKeywords(KeywordUpdate, KeywordDelete, KeywordUser, KeywordRole, KeywordQuota):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\tcase p.matchOneOfKeywords(KeywordAdd, KeywordDrop, KeywordModify, KeywordClear, KeywordComment, KeywordRename, KeywordMaterialized):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\t\tswitch {\n\t\tcase p.tryConsumeKeywords(KeywordColumn):\n\t\t\tkeywords = append(keywords, KeywordColumn)\n\t\tcase p.tryConsumeKeywords(KeywordIndex):\n\t\t\tkeywords = append(keywords, KeywordIndex)\n\t\t\tkeywords = append(keywords, KeywordConstraint)\n\t\tcase p.tryConsumeKeywords(KeywordTtl):\n\t\t\tkeywords = append(keywords, KeywordTtl)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected COLUMN|INDEX\")\n\t\t}\n\tcase p.tryConsumeKeywords(KeywordOrder):\n\t\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordOrder, KeywordBy)\n\tcase p.tryConsumeKeywords(KeywordSample):\n\t\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordSample, KeywordBy)\n\tcase p.tryConsumeKeywords(KeywordSettings):\n\t\tkeywords = append(keywords, KeywordSettings)\n\tcase p.tryConsumeKeywords(KeywordView):\n\t\tkeywords = append(keywords, KeywordView)\n\t\tswitch {\n\t\tcase p.tryConsumeKeywords(KeywordModify):\n\t\t\tkeywords = append(keywords, KeywordModify)\n\t\tcase p.tryConsumeKeywords(KeywordRefresh):\n\t\t\tkeywords = append(keywords, KeywordRefresh)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected MODIFY|REFRESH\")\n\t\t}\n\tcase p.matchOneOfKeywords(KeywordMove, KeywordFreeze):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\t\tif err := p.expectKeyword(KeywordPartition); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordPartition)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected UPDATE|DELETE|ADD|DROP|MODIFY|CLEAR|COMMENT|RENAME|MATERIALIZED|ORDER|SAMPLE|SETTINGS|VIEW|MOVE|FREEZE\")\n\t}\n\treturn &PrivilegeClause{\n\t\tPrivilegePos: pos,\n\t\tKeywords:     keywords,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeCreate(pos Pos) (*PrivilegeClause, error) {\n\tkeywords := []string{KeywordCreate}\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordDatabase, KeywordDictionary, KeywordTable, KeywordFunction, KeywordView, KeywordUser, KeywordRole, KeywordQuota):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\tcase p.tryConsumeKeywords(KeywordTemporary):\n\t\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordTemporary, KeywordTable)\n\tcase p.tryConsumeKeywords(KeywordRows):\n\t\tif err := p.expectKeyword(KeywordPolicy); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordRows, KeywordPolicy)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected DATABASE|DICTIONARY|TABLE|FUNCTION|VIEW|USER|ROLE|ROWS\")\n\t}\n\treturn &PrivilegeClause{\n\t\tPrivilegePos: pos,\n\t\tKeywords:     keywords,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeDrop(pos Pos) (*PrivilegeClause, error) {\n\tkeywords := []string{KeywordDrop}\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordDatabase, KeywordDictionary, KeywordUser, KeywordRole, KeywordQuota, KeywordTable, KeywordFunction, KeywordView):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected DATABASE|DICTIONARY|TABLE|FUNCTION|VIEW\")\n\t}\n\treturn &PrivilegeClause{\n\t\tPrivilegePos: pos,\n\t\tKeywords:     keywords,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeShow(pos Pos) (*PrivilegeClause, error) {\n\tkeywords := []string{KeywordShow}\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordDatabases, KeywordDictionaries, KeywordTables, KeywordColumns):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected DATABASES|DICTIONARIES|TABLES|COLUMNS\")\n\t}\n\treturn &PrivilegeClause{\n\t\tPrivilegePos: pos,\n\t\tKeywords:     keywords,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeSystem(pos Pos) (*PrivilegeClause, error) {\n\tkeywords := []string{KeywordShow}\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordShutdown, KeywordMerges, KeywordFetches, KeywordSends, KeywordMoves, KeywordCluster):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\tcase p.tryConsumeKeywords(KeywordDrop):\n\t\tkeywords = append(keywords, KeywordDrop)\n\t\tswitch {\n\t\tcase p.tryConsumeKeywords(KeywordCache):\n\t\t\tkeywords = append(keywords, KeywordCache)\n\t\tcase p.matchOneOfKeywords(KeywordMark, KeywordDNS, KeywordUncompressed):\n\t\t\tkeyword := p.last().String\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tkeywords = append(keywords, keyword)\n\t\t\tif err := p.expectKeyword(KeywordCache); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tkeywords = append(keywords, KeywordCache)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected CACHE|MARK|DNS|UNCOMPRESSED\")\n\t\t}\n\tcase p.tryConsumeKeywords(KeywordReload):\n\t\tkeywords = append(keywords, KeywordReload)\n\t\tswitch {\n\t\tcase p.matchOneOfKeywords(KeywordDictionary, KeywordFunction, KeywordFunctions, KeywordConfig):\n\t\t\tkeyword := p.last().String\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tkeywords = append(keywords, keyword)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected DICTIONARY|FUNCTION|FUNCTIONS|CONFIG\")\n\t\t}\n\tcase p.tryConsumeKeywords(KeywordFlush):\n\t\tkeywords = append(keywords, KeywordFlush)\n\t\tswitch {\n\t\tcase p.matchOneOfKeywords(KeywordLogs, KeywordDistributed):\n\t\t\tkeyword := p.last().String\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tkeywords = append(keywords, keyword)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected LOGS|DISTRIBUTED\")\n\t\t}\n\tcase p.tryConsumeKeywords(KeywordTtl):\n\t\tkeywords = append(keywords, KeywordTtl)\n\t\tif err := p.expectKeyword(KeywordMerges); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordMerges)\n\tcase p.matchOneOfKeywords(KeywordSync, KeywordRestart):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\tkeywords = append(keywords, keyword)\n\t\tif err := p.expectKeyword(KeywordReplica); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordReplica)\n\tcase p.tryConsumeKeywords(KeywordReplication):\n\t\tkeywords = append(keywords, KeywordReplication)\n\t\tif err := p.expectKeyword(KeywordQueues); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeywords = append(keywords, KeywordQueues)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected QUEUES|SHUTDOWN|MERGES|FETCHES|SENDS|MOVES|CLUSTER|DROP|RELOAD|FLUSH|TTL|SYNC|RESTART|REPLICATION\")\n\t}\n\treturn &PrivilegeClause{\n\t\tPrivilegePos: pos,\n\t\tKeywords:     keywords,\n\t}, nil\n}\n\nfunc (p *Parser) parsePrivilegeClause(pos Pos) (*PrivilegeClause, error) {\n\tif p.matchTokenKind(TokenKindIdent) {\n\t\tif p.last().String == \"dictGet\" {\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\treturn &PrivilegeClause{\n\t\t\t\tPrivilegePos: pos,\n\t\t\t\tKeywords:     []string{\"dictGet\"},\n\t\t\t}, nil\n\t\t}\n\t}\n\tswitch {\n\tcase p.matchOneOfKeywords(KeywordSelect, KeywordInsert):\n\t\treturn p.parsePrivilegeSelectOrInsert(pos)\n\tcase p.tryConsumeKeywords(KeywordAlter):\n\t\treturn p.parsePrivilegeAlter(pos)\n\tcase p.tryConsumeKeywords(KeywordCreate):\n\t\treturn p.parsePrivilegeCreate(pos)\n\tcase p.tryConsumeKeywords(KeywordDrop):\n\t\treturn p.parsePrivilegeDrop(pos)\n\tcase p.tryConsumeKeywords(KeywordShow):\n\t\treturn p.parsePrivilegeShow(pos)\n\tcase p.matchKeyword(KeywordAll), p.matchTokenKind(KeywordNone):\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &PrivilegeClause{\n\t\t\tPrivilegePos: pos,\n\t\t\tKeywords:     []string{KeywordAll},\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordKill):\n\t\tif err := p.expectKeyword(KeywordQuery); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &PrivilegeClause{\n\t\t\tPrivilegePos: pos,\n\t\t\tKeywords:     []string{KeywordKill, KeywordQuery},\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordSystem):\n\t\treturn p.parsePrivilegeSystem(pos)\n\tcase p.tryConsumeKeywords(KeywordAdmin):\n\t\tif err := p.expectKeyword(KeywordOption); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &PrivilegeClause{\n\t\t\tPrivilegePos: pos,\n\t\t\tKeywords:     []string{KeywordAdmin, KeywordOption},\n\t\t}, nil\n\tcase p.matchOneOfKeywords(KeywordOptimize, KeywordTruncate):\n\t\tkeyword := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &PrivilegeClause{\n\t\t\tPrivilegePos: pos,\n\t\t\tKeywords:     []string{keyword},\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordRole):\n\t\tif err := p.expectKeyword(KeywordAdmin); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &PrivilegeClause{\n\t\t\tPrivilegePos: pos,\n\t\t\tKeywords:     []string{KeywordRole, KeywordAdmin},\n\t\t}, nil\n\t}\n\treturn nil, fmt.Errorf(\"expected SELECT|INSERT|ALTER|CREATE|DROP|SHOW|KILL|SYSTEM|OPTIMIZE|TRUNCATE\")\n}\n\nfunc (p *Parser) parsePrivilegeRoles(_ Pos) ([]*Ident, error) {\n\troles := make([]*Ident, 0)\n\trole, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troles = append(roles, role)\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\trole, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troles = append(roles, role)\n\t}\n\treturn roles, nil\n}\n\nfunc (p *Parser) parseGrantOptions(_ Pos) ([]string, error) {\n\toptions := make([]string, 0)\n\tfor p.matchKeyword(KeywordWith) {\n\t\toption, err := p.parseGrantOption(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\toptions = append(options, option)\n\t}\n\treturn options, nil\n}\n\nfunc (p *Parser) parseGrantOption(_ Pos) (string, error) {\n\tif err := p.expectKeyword(KeywordWith); err != nil {\n\t\treturn \"\", err\n\t}\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := p.expectKeyword(KeywordOption); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn ident.Name, nil\n}\n\nfunc (p *Parser) parseGrantSource(_ Pos) (*TableIdentifier, error) {\n\tident, err := p.parseIdentOrStar()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif p.tryConsumeTokenKind(TokenKindDot) == nil {\n\t\treturn &TableIdentifier{\n\t\t\tTable: ident,\n\t\t}, nil\n\t}\n\tdotIdent, err := p.parseIdentOrStar()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &TableIdentifier{\n\t\tDatabase: ident,\n\t\tTable:    dotIdent,\n\t}, nil\n}\n\nfunc (p *Parser) parseGrantPrivilegeStmt(pos Pos) (*GrantPrivilegeStmt, error) {\n\tif err := p.expectKeyword(KeywordGrant); err != nil {\n\t\treturn nil, err\n\t}\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar privileges []*PrivilegeClause\n\tprivilege, err := p.parsePrivilegeClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tprivileges = append(privileges, privilege)\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tprivilege, err := p.parsePrivilegeClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tprivileges = append(privileges, privilege)\n\t}\n\tstatementEnd := privileges[len(privileges)-1].End()\n\n\tif err := p.expectKeyword(KeywordOn); err != nil {\n\t\treturn nil, err\n\t}\n\ton, err := p.parseGrantSource(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordTo); err != nil {\n\t\treturn nil, err\n\t}\n\ttoRoles, err := p.parsePrivilegeRoles(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(toRoles) != 0 {\n\t\tstatementEnd = toRoles[len(toRoles)-1].NameEnd\n\t}\n\toptions, err := p.parseGrantOptions(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(options) != 0 {\n\t\tstatementEnd = p.End()\n\t}\n\n\treturn &GrantPrivilegeStmt{\n\t\tGrantPos:     pos,\n\t\tStatementEnd: statementEnd,\n\t\tOnCluster:    onCluster,\n\t\tPrivileges:   privileges,\n\t\tOn:           on,\n\t\tTo:           toRoles,\n\t\tWithOptions:  options,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterRole(pos Pos) (*AlterRole, error) {\n\tif err := p.expectKeyword(KeywordRole); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\troleRenamePairs := make([]*RoleRenamePair, 0)\n\troleRenamePair, err := p.parseRoleRenamePair(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troleRenamePairs = append(roleRenamePairs, roleRenamePair)\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\troleRenamePair, err := p.parseRoleRenamePair(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troleRenamePairs = append(roleRenamePairs, roleRenamePair)\n\t}\n\tstatementEnd := roleRenamePairs[len(roleRenamePairs)-1].End()\n\n\tsettings, err := p.tryParseRoleSettings(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif settings != nil {\n\t\tstatementEnd = settings[len(settings)-1].End()\n\t}\n\n\treturn &AlterRole{\n\t\tAlterPos:        pos,\n\t\tStatementEnd:    statementEnd,\n\t\tIfExists:        ifExists,\n\t\tRoleRenamePairs: roleRenamePairs,\n\t\tSettings:        settings,\n\t}, nil\n}\n\nfunc (p *Parser) parseRoleRenamePair(_ Pos) (*RoleRenamePair, error) {\n\troleName, err := p.parseRoleName(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troleRenamePair := &RoleRenamePair{\n\t\tRoleName:     roleName,\n\t\tStatementEnd: roleName.End(),\n\t}\n\tif p.tryConsumeKeywords(KeywordRename) {\n\t\tif err := p.expectKeyword(KeywordTo); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnewName, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troleRenamePair.NewName = newName\n\t\troleRenamePair.StatementEnd = newName.NameEnd\n\t}\n\treturn roleRenamePair, nil\n}\n"
  },
  {
    "path": "parser/parser_alter.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nfunc (p *Parser) parseAlterTable(pos Pos) (*AlterTable, error) {\n\talterTable := &AlterTable{\n\t\tAlterPos:   pos,\n\t\tAlterExprs: make([]AlterTableClause, 0),\n\t}\n\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\talterTable.TableIdentifier = tableIdentifier\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\talterTable.OnCluster = onCluster\n\n\tfor !p.lexer.isEOF() {\n\t\tvar alter AlterTableClause\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordAdd):\n\t\t\talter, err = p.parseAlterTableAdd(p.Pos())\n\t\tcase p.matchKeyword(KeywordDrop):\n\t\t\talter, err = p.parseAlterTableDrop(p.Pos())\n\t\tcase p.matchKeyword(KeywordAttach):\n\t\t\talter, err = p.parseAlterTableAttachPartition(p.Pos())\n\t\tcase p.matchKeyword(KeywordDetach):\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\talter, err = p.parseAlterTableDetachPartition(p.Pos())\n\t\tcase p.matchKeyword(KeywordFreeze):\n\t\t\talter, err = p.parseAlterTableFreezePartition(p.Pos())\n\t\tcase p.matchKeyword(KeywordRemove):\n\t\t\talter, err = p.parseAlterTableRemoveTTL(p.Pos())\n\t\tcase p.matchKeyword(KeywordRename):\n\t\t\talter, err = p.parseAlterTableRenameColumn(p.Pos())\n\t\tcase p.matchKeyword(KeywordClear):\n\t\t\talter, err = p.parseAlterTableClear(p.Pos())\n\t\tcase p.matchKeyword(KeywordModify):\n\t\t\talter, err = p.parseAlterTableModify(p.Pos())\n\t\tcase p.matchKeyword(KeywordReplace):\n\t\t\talter, err = p.parseAlterTableReplacePartition(p.Pos())\n\t\tcase p.matchKeyword(KeywordMaterialize):\n\t\t\talter, err = p.parseAlterTableMaterialize(p.Pos())\n\t\tcase p.matchKeyword(KeywordReset):\n\t\t\talter, err = p.parseAlterTableReset(p.Pos())\n\t\tcase p.matchKeyword(KeywordDelete):\n\t\t\talter, err = p.parseAlterTableDelete(p.Pos())\n\t\tcase p.matchKeyword(KeywordUpdate):\n\t\t\talter, err = p.parseAlterTableUpdate(p.Pos())\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"expected token: ADD|DROP|ATTACH|DETACH|FREEZE|REMOVE|CLEAR|MODIFY|REPLACE|MATERIALIZE|RESET|DELETE|UPDATE\")\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\talterTable.AlterExprs = append(alterTable.AlterExprs, alter)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tif len(alterTable.AlterExprs) == 0 {\n\t\treturn nil, errors.New(\"expected token: ADD|DROP\")\n\t}\n\talterTable.StatementEnd = alterTable.AlterExprs[len(alterTable.AlterExprs)-1].End()\n\n\treturn alterTable, nil\n}\n\nfunc (p *Parser) parseAlterTableAdd(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordAdd); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch {\n\tcase p.matchKeyword(KeywordColumn):\n\t\treturn p.parseAlterTableAddColumn(pos)\n\tcase p.matchKeyword(KeywordIndex):\n\t\treturn p.parseAlterTableAddIndex(pos)\n\tcase p.matchKeyword(KeywordProjection):\n\t\treturn p.parseAlterTableAddProjection(pos)\n\tdefault:\n\t\treturn nil, errors.New(\"expected token: COLUMN|INDEX|PROJECTION\")\n\t}\n}\n\nfunc (p *Parser) parseAlterTableAddColumn(pos Pos) (*AlterTableAddColumn, error) {\n\tif err := p.expectKeyword(KeywordColumn); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifNotExists, err := p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumn, err := p.parseTableColumnExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatementEnd := column.End()\n\n\tafter, err := p.tryParseAfterClause()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif after != nil {\n\t\tstatementEnd = after.End()\n\t}\n\n\tsettings, err := p.tryParseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif settings != nil {\n\t\tstatementEnd = settings.End()\n\t}\n\n\treturn &AlterTableAddColumn{\n\t\tAddPos:       pos,\n\t\tStatementEnd: statementEnd,\n\t\tColumn:       column,\n\t\tIfNotExists:  ifNotExists,\n\t\tAfter:        after,\n\t\tSettings:     settings,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableAddIndex(pos Pos) (*AlterTableAddIndex, error) {\n\tindexPos := p.Pos()\n\tif err := p.expectKeyword(KeywordIndex); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifNotExists, err := p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tindex, err := p.parseTableIndex(indexPos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatementEnd := index.End()\n\tafter, err := p.tryParseAfterClause()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif after != nil {\n\t\tstatementEnd = after.End()\n\t}\n\treturn &AlterTableAddIndex{\n\t\tAddPos:       pos,\n\t\tStatementEnd: statementEnd,\n\t\tIfNotExists:  ifNotExists,\n\t\tIndex:        index,\n\t\tAfter:        after,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseProjectionOrderBy(pos Pos) (*ProjectionOrderByClause, error) {\n\tif !p.tryConsumeKeywords(KeywordOrder) {\n\t\treturn nil, nil // nolint\n\t}\n\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\treturn nil, err\n\t}\n\tcolumns, err := p.parseColumnExprList(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ProjectionOrderByClause{\n\t\tOrderByPos: pos,\n\t\tColumns:    columns,\n\t}, nil\n}\n\nfunc (p *Parser) parseProjectionSelect(pos Pos) (*ProjectionSelectStmt, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\twith, err := p.tryParseWithClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordSelect); err != nil {\n\t\treturn nil, err\n\t}\n\tcolumns, err := p.parseColumnExprList(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgroupBy, err := p.tryParseGroupByClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\torderBy, err := p.tryParseProjectionOrderBy(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlastToken := p.last()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ProjectionSelectStmt{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: lastToken.Pos,\n\t\tWith:          with,\n\t\tSelectColumns: columns,\n\t\tGroupBy:       groupBy,\n\t\tOrderBy:       orderBy,\n\t}, nil\n}\n\nfunc (p *Parser) parseTableProjection(pos Pos, includeProjectionKeyword bool) (*TableProjection, error) {\n\tif includeProjectionKeyword {\n\t\tif err := p.expectKeyword(KeywordProjection); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tidentifier, err := p.ParseNestedIdentifier(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tselectExpr, err := p.parseProjectionSelect(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &TableProjection{\n\t\tIncludeProjectionKeyword: includeProjectionKeyword,\n\t\tProjectionPos:            pos,\n\t\tIdentifier:               identifier,\n\t\tSelect:                   selectExpr,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableAddProjection(pos Pos) (*AlterTableAddProjection, error) {\n\tif err := p.expectKeyword(KeywordProjection); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifNotExists, err := p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttableProjection, err := p.parseTableProjection(p.Pos(), false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatementEnd := tableProjection.End()\n\tafter, err := p.tryParseAfterClause()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif after != nil {\n\t\tstatementEnd = after.End()\n\t}\n\treturn &AlterTableAddProjection{\n\t\tAddPos:          pos,\n\t\tStatementEnd:    statementEnd,\n\t\tIfNotExists:     ifNotExists,\n\t\tTableProjection: tableProjection,\n\t\tAfter:           after,\n\t}, nil\n}\n\nfunc (p *Parser) parseTableIndex(pos Pos) (*TableIndex, error) {\n\tname, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumnExpr, err := p.parseColumnsExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordType); err != nil {\n\t\treturn nil, err\n\t}\n\tcolumnType, err := p.parseColumnType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordGranularity); err != nil {\n\t\treturn nil, err\n\t}\n\tgranularity, err := p.parseDecimal(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &TableIndex{\n\t\tIndexPos:    pos,\n\t\tName:        name,\n\t\tColumnExpr:  columnExpr,\n\t\tColumnType:  columnType,\n\t\tGranularity: granularity,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableDrop(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordDrop); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch {\n\tcase p.matchKeyword(KeywordColumn), p.matchKeyword(KeywordIndex), p.matchKeyword(KeywordProjection):\n\t\treturn p.parseAlterTableDropClause(pos)\n\tcase p.matchKeyword(KeywordDetached), p.matchKeyword(KeywordPartition):\n\t\treturn p.parseAlterTableDropPartition(pos)\n\tdefault:\n\t\treturn nil, errors.New(\"expected keyword: COLUMN|INDEX|PROJECTION|DETACHED|PARTITION\")\n\t}\n}\n\n// Syntax: ALTER TABLE DETACH partitionClause\nfunc (p *Parser) parseAlterTableDetachPartition(pos Pos) (AlterTableClause, error) {\n\tpartitionPos := p.Pos()\n\tif err := p.expectKeyword(KeywordPartition); err != nil {\n\t\treturn nil, err\n\t}\n\tpartition := &PartitionClause{\n\t\tPartitionPos: partitionPos,\n\t}\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpartition.Expr = expr\n\n\tsettings, err := p.tryParseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableDetachPartition{\n\t\tDetachPos: pos,\n\t\tPartition: partition,\n\t\tSettings:  settings,\n\t}, nil\n}\n\nfunc (p *Parser) tryParsePartitionClause(pos Pos) (*PartitionClause, error) {\n\tif !p.matchKeyword(KeywordPartition) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parsePartitionClause(pos)\n}\n\nfunc (p *Parser) parsePartitionClause(pos Pos) (*PartitionClause, error) {\n\tif err := p.expectKeyword(KeywordPartition); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpartition := &PartitionClause{\n\t\tPartitionPos: pos,\n\t}\n\tif p.tryConsumeKeywords(KeywordId) {\n\t\tid, err := p.parseString(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpartition.ID = id\n\t} else if p.tryConsumeKeywords(KeywordAll) {\n\t\tpartition.All = true\n\t} else {\n\t\texpr, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpartition.Expr = expr\n\t}\n\treturn partition, nil\n}\n\n// Syntax: ALTER TABLE ATTACH partitionClause (FROM tableIdentifier)?\nfunc (p *Parser) parseAlterTableAttachPartition(pos Pos) (AlterTableClause, error) {\n\talterTable := &AlterTableAttachPartition{AttachPos: pos}\n\n\tif err := p.expectKeyword(KeywordAttach); err != nil {\n\t\treturn nil, err\n\t}\n\tpartition, err := p.parsePartitionClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\talterTable.Partition = partition\n\t// FROM [db.]table?\n\tif p.tryConsumeKeywords(KeywordFrom) {\n\t\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\talterTable.From = tableIdentifier\n\t}\n\treturn alterTable, nil\n}\n\nfunc (p *Parser) parseAlterTableDropClause(pos Pos) (AlterTableClause, error) {\n\tvar kind string\n\tswitch {\n\tcase p.matchKeyword(KeywordColumn):\n\t\tkind = KeywordColumn\n\tcase p.matchKeyword(KeywordIndex):\n\t\tkind = KeywordIndex\n\tcase p.matchKeyword(KeywordProjection):\n\t\tkind = KeywordProjection\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected token: COLUMN|INDEX|PROJECTION, but got %s\", p.lastTokenKind())\n\t}\n\t_ = p.lexer.consumeToken()\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif kind == KeywordProjection {\n\t\treturn &AlterTableDropProjection{\n\t\t\tDropPos:        pos,\n\t\t\tProjectionName: name,\n\t\t\tIfExists:       ifExists,\n\t\t}, nil\n\t} else if kind == KeywordColumn {\n\t\treturn &AlterTableDropColumn{\n\t\t\tDropPos:    pos,\n\t\t\tColumnName: name,\n\t\t\tIfExists:   ifExists,\n\t\t}, nil\n\t} else {\n\t\treturn &AlterTableDropIndex{\n\t\t\tDropPos:   pos,\n\t\t\tIndexName: name,\n\t\t\tIfExists:  ifExists,\n\t\t}, nil\n\t}\n}\n\nfunc (p *Parser) tryParseAfterClause() (*NestedIdentifier, error) {\n\tif !p.tryConsumeKeywords(KeywordAfter) {\n\t\treturn nil, nil // nolint\n\t}\n\n\treturn p.ParseNestedIdentifier(p.Pos())\n}\n\n// Syntax: ALTER TABLE DROP partitionClause\nfunc (p *Parser) parseAlterTableDropPartition(pos Pos) (AlterTableClause, error) {\n\tvar hasDetached bool\n\tif p.matchKeyword(KeywordDetached) {\n\t\t_ = p.lexer.consumeToken()\n\t\thasDetached = true\n\t}\n\tpartitionPos := p.Pos()\n\tif err := p.expectKeyword(KeywordPartition); err != nil {\n\t\treturn nil, err\n\t}\n\tpartition := &PartitionClause{\n\t\tPartitionPos: partitionPos,\n\t}\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpartition.Expr = expr\n\n\tsettings, err := p.tryParseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableDropPartition{\n\t\tDropPos:     pos,\n\t\tPartition:   partition,\n\t\tHasDetached: hasDetached,\n\t\tSettings:    settings,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableFreezePartition(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordFreeze); err != nil {\n\t\treturn nil, err\n\t}\n\talterTable := &AlterTableFreezePartition{\n\t\tFreezePos:    pos,\n\t\tStatementEnd: p.Pos(),\n\t}\n\tif p.matchKeyword(KeywordPartition) {\n\t\tpartition, err := p.parsePartitionClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\talterTable.Partition = partition\n\t\talterTable.StatementEnd = partition.End()\n\t}\n\n\treturn alterTable, nil\n}\n\nfunc (p *Parser) parseAlterTableRemoveTTL(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordRemove); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordTtl); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableRemoveTTL{\n\t\tRemovePos:    pos,\n\t\tStatementEnd: p.Pos(),\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableClear(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordClear); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p.parseAlterTableClearClause(pos)\n}\n\n// Syntax: ALTER TABLE CLEAR COLUMN|INDEX|PROJECTION (IF EXISTS)? nestedIdentifier (IN partitionClause)?\nfunc (p *Parser) parseAlterTableClearClause(pos Pos) (AlterTableClause, error) {\n\tvar kind string\n\tswitch {\n\tcase p.matchKeyword(KeywordColumn):\n\t\tkind = KeywordColumn\n\tcase p.matchKeyword(KeywordIndex):\n\t\tkind = KeywordIndex\n\tcase p.matchKeyword(KeywordProjection):\n\t\tkind = KeywordProjection\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected keyword: COLUMN|INDEX|PROJECTION, but got %q\", p.lastTokenKind())\n\t}\n\t_ = p.lexer.consumeToken()\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatementEnd := name.End()\n\n\tvar partition *PartitionClause\n\tif p.tryConsumeKeywords(KeywordIn) {\n\t\tpartition, err = p.tryParsePartitionClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif partition != nil {\n\t\t\tstatementEnd = partition.End()\n\t\t}\n\t}\n\n\tif kind == KeywordProjection {\n\t\treturn &AlterTableClearProjection{\n\t\t\tClearPos:       pos,\n\t\t\tStatementEnd:   statementEnd,\n\t\t\tIfExists:       ifExists,\n\t\t\tProjectionName: name,\n\t\t\tPartitionExpr:  partition,\n\t\t}, nil\n\t} else if kind == KeywordColumn {\n\t\treturn &AlterTableClearColumn{\n\t\t\tClearPos:      pos,\n\t\t\tStatementEnd:  statementEnd,\n\t\t\tIfExists:      ifExists,\n\t\t\tColumnName:    name,\n\t\t\tPartitionExpr: partition,\n\t\t}, nil\n\t} else {\n\t\treturn &AlterTableClearIndex{\n\t\t\tClearPos:      pos,\n\t\t\tStatementEnd:  statementEnd,\n\t\t\tIfExists:      ifExists,\n\t\t\tIndexName:     name,\n\t\t\tPartitionExpr: partition,\n\t\t}, nil\n\t}\n}\n\n// Syntax: ALTER TABLE RENAME COLUMN (IF EXISTS)? nestedIdentifier TO nestedIdentifier\nfunc (p *Parser) parseAlterTableRenameColumn(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordRename); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordColumn); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\toldColumnName, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = p.expectKeyword(KeywordTo); err != nil {\n\t\treturn nil, err\n\t}\n\n\tnewColumnName, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableRenameColumn{\n\t\tRenamePos:     pos,\n\t\tIfExists:      ifExists,\n\t\tOldColumnName: oldColumnName,\n\t\tNewColumnName: newColumnName,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableModify(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordModify); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch {\n\tcase p.matchKeyword(KeywordColumn):\n\t\treturn p.parseAlterTableModifyColumn(pos)\n\tcase p.matchKeyword(KeywordTtl):\n\t\tttlPos := p.Pos()\n\t\t_ = p.lexer.consumeToken()\n\t\titems, err := p.parseTTLClause(ttlPos, true)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlistEnd := ttlPos\n\t\tif len(items) > 0 {\n\t\t\tlistEnd = items[len(items)-1].End()\n\t\t}\n\t\tttlClause := &TTLClause{\n\t\t\tTTLPos:  ttlPos,\n\t\t\tListEnd: listEnd,\n\t\t\tItems:   items,\n\t\t}\n\t\treturn &AlterTableModifyTTL{\n\t\t\tModifyPos:    pos,\n\t\t\tStatementEnd: ttlClause.End(),\n\t\t\tTTL:          ttlClause,\n\t\t}, nil\n\tcase p.matchKeyword(KeywordQuery):\n\t\t_ = p.lexer.consumeToken()\n\t\tselectQuery, err := p.parseSelectQuery(pos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &AlterTableModifyQuery{\n\t\t\tModifyPos:    pos,\n\t\t\tStatementEnd: selectQuery.End(),\n\t\t\tSelectExpr:   selectQuery,\n\t\t}, nil\n\tcase p.matchKeyword(KeywordSetting):\n\t\t_ = p.lexer.consumeToken() // consume \"SETTING\"\n\t\tsettings, err := p.parseSettingsList(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// settings must not be empty\n\t\tstatementEnd := settings[len(settings)-1].End()\n\t\treturn &AlterTableModifySetting{\n\t\t\tModifyPos:    pos,\n\t\t\tStatementEnd: statementEnd,\n\t\t\tSettings:     settings,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected keyword: COLUMN|TTL|QUERY|SETTING, but got %q\",\n\t\t\tp.last().String)\n\t}\n\n}\n\n// syntax: MODIFY COLUMN (IF EXISTS)? tableColumnDfnt\nfunc (p *Parser) parseAlterTableModifyColumn(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordColumn); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// at least parse out column name\n\tcolumn, err := p.parseTableColumnExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\talterTableModifyColumn := &AlterTableModifyColumn{\n\t\tModifyPos:    pos,\n\t\tStatementEnd: column.End(),\n\t\tIfExists:     ifExists,\n\t\tColumn:       column,\n\t}\n\n\t// syntax: MODIFY COLUMN (IF EXISTS)? nestedIdentifier REMOVE tableColumnPropertyType\n\tremovePropertyType, err := p.tryParseRemovePropertyTypeExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\talterTableModifyColumn.RemovePropertyType = removePropertyType\n\n\treturn alterTableModifyColumn, nil\n}\n\nfunc (p *Parser) tryParseRemovePropertyTypeExpr(pos Pos) (*RemovePropertyType, error) {\n\tif !p.matchKeyword(KeywordRemove) {\n\t\treturn nil, nil\n\t}\n\n\tif err := p.expectKeyword(KeywordRemove); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumnPropertyType, err := p.parseColumnPropertyType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &RemovePropertyType{\n\t\tRemovePos:    pos,\n\t\tPropertyType: columnPropertyType,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableReplacePartition(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordReplace); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpartition, err := p.parsePartitionClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = p.expectKeyword(KeywordFrom); err != nil {\n\t\treturn nil, err\n\t}\n\n\ttable, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableReplacePartition{\n\t\tReplacePos: pos,\n\t\tPartition:  partition,\n\t\tTable:      table,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableMaterialize(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordMaterialize); err != nil {\n\t\treturn nil, err\n\t}\n\tvar kind string\n\tswitch {\n\tcase p.matchKeyword(KeywordIndex):\n\t\tkind = KeywordIndex\n\tcase p.matchKeyword(KeywordProjection):\n\t\tkind = KeywordProjection\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected keyword: INDEX|PROJECTION, but got %q\", p.lastTokenKind())\n\t}\n\t_ = p.lexer.consumeToken()\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatementEnd := name.End()\n\tvar partition *PartitionClause\n\tif p.tryConsumeKeywords(KeywordIn) {\n\t\tpartition, err = p.tryParsePartitionClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstatementEnd = partition.End()\n\t}\n\tif kind == KeywordIndex {\n\t\treturn &AlterTableMaterializeIndex{\n\t\t\tMaterializedPos: pos,\n\t\t\tStatementEnd:    statementEnd,\n\t\t\tIfExists:        ifExists,\n\t\t\tIndexName:       name,\n\t\t\tPartition:       partition,\n\t\t}, nil\n\t}\n\treturn &AlterTableMaterializeProjection{\n\t\tMaterializedPos: pos,\n\t\tStatementEnd:    statementEnd,\n\t\tIfExists:        ifExists,\n\t\tProjectionName:  name,\n\t\tPartition:       partition,\n\t}, nil\n}\n\nfunc (p *Parser) parseAlterTableReset(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordReset); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordSetting); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Parse comma-separated setting names inline\n\tvar settings []*Ident\n\tsetting, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsettings = append(settings, setting)\n\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tsetting, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsettings = append(settings, setting)\n\t}\n\n\tstatementEnd := settings[len(settings)-1].End()\n\n\treturn &AlterTableResetSetting{\n\t\tResetPos:     pos,\n\t\tStatementEnd: statementEnd,\n\t\tSettings:     settings,\n\t}, nil\n}\n\n// Syntax: ALTER TABLE DELETE WHERE condition\nfunc (p *Parser) parseAlterTableDelete(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordDelete); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordWhere); err != nil {\n\t\treturn nil, err\n\t}\n\n\twhereExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableDelete{\n\t\tDeletePos:    pos,\n\t\tStatementEnd: whereExpr.End(),\n\t\tWhereClause:  whereExpr,\n\t}, nil\n}\n\n// Syntax: ALTER TABLE UPDATE column1 = expr1 [, column2 = expr2, ...] [IN PARTITION partition_id] WHERE condition\nfunc (p *Parser) parseAlterTableUpdate(pos Pos) (AlterTableClause, error) {\n\tif err := p.expectKeyword(KeywordUpdate); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Parse at least one assignment\n\tassignments := make([]*UpdateAssignment, 0)\n\tassignment, err := p.parseUpdateAssignment(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tassignments = append(assignments, assignment)\n\n\t// Parse additional comma-separated assignments\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tassignment, err = p.parseUpdateAssignment(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tassignments = append(assignments, assignment)\n\t}\n\n\tvar inPartition *PartitionClause\n\tif p.tryConsumeKeywords(KeywordIn) {\n\t\tinPartition, err = p.parsePartitionClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif err := p.expectKeyword(KeywordWhere); err != nil {\n\t\treturn nil, err\n\t}\n\n\twhereExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AlterTableUpdate{\n\t\tUpdatePos:    pos,\n\t\tStatementEnd: whereExpr.End(),\n\t\tAssignments:  assignments,\n\t\tInPartition:  inPartition,\n\t\tWhereClause:  whereExpr,\n\t}, nil\n}\n\n// Parse column = expression assignment\nfunc (p *Parser) parseUpdateAssignment(pos Pos) (*UpdateAssignment, error) {\n\tcolumn, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Why don't we use parseExpr here? Because `ALTER TABLE UPDATE` syntax allows to\n\t// use `IN PARTITION` keywords after assignments. So we need to limit the precedence\n\t// to avoid parsing `IN PARTITION` as part of the expression.\n\texpr, err := p.parseSubExpr(p.Pos(), precedenceIn)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &UpdateAssignment{\n\t\tAssignmentPos: pos,\n\t\tColumn:        column,\n\t\tExpr:          expr,\n\t}, nil\n}\n"
  },
  {
    "path": "parser/parser_column.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nconst (\n\tPrecedenceUnknown = iota\n\tPrecedenceOr\n\tPrecedenceAnd\n\tPrecedenceQuery\n\tPrecedenceNot\n\tPrecedenceGlobal\n\tPrecedenceIs\n\tPrecedenceCompare\n\tPrecedenceBetweenLike\n\tprecedenceIn\n\tPrecedenceConcat\n\tPrecedenceAddSub\n\tPrecedenceMulDivMod\n\tPrecedenceBracket\n\tPrecedenceArrow\n\tPrecedenceDot\n\tPrecedenceDoubleColon\n)\n\nfunc (p *Parser) tryParseColumnComment(pos Pos) (*StringLiteral, error) {\n\tif !p.tryConsumeKeywords(KeywordComment) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseString(pos)\n}\n\nfunc (p *Parser) getNextPrecedence() int {\n\tswitch {\n\tcase p.matchKeyword(KeywordOr):\n\t\treturn PrecedenceOr\n\tcase p.matchKeyword(KeywordAnd):\n\t\treturn PrecedenceAnd\n\tcase p.matchKeyword(KeywordIs):\n\t\treturn PrecedenceIs\n\tcase p.matchKeyword(KeywordNot):\n\t\treturn PrecedenceNot\n\tcase p.matchTokenKind(TokenKindDot):\n\t\treturn PrecedenceDot\n\tcase p.matchTokenKind(TokenKindDash):\n\t\treturn PrecedenceDoubleColon\n\tcase p.matchTokenKind(TokenKindSingleEQ), p.matchTokenKind(TokenKindLT), p.matchTokenKind(TokenKindLE),\n\t\tp.matchTokenKind(TokenKindGE), p.matchTokenKind(TokenKindGT), p.matchTokenKind(TokenKindDoubleEQ),\n\t\tp.matchTokenKind(TokenKindNE), p.matchTokenKind(\"<>\"):\n\t\treturn PrecedenceCompare\n\tcase p.matchTokenKind(TokenKindConcat):\n\t\treturn PrecedenceConcat\n\tcase p.matchTokenKind(TokenKindPlus), p.matchTokenKind(TokenKindMinus):\n\t\treturn PrecedenceAddSub\n\tcase p.matchTokenKind(TokenKindMul), p.matchTokenKind(TokenKindDiv), p.matchTokenKind(TokenKindMod):\n\t\treturn PrecedenceMulDivMod\n\tcase p.matchTokenKind(TokenKindArrow):\n\t\treturn PrecedenceArrow\n\tcase p.matchTokenKind(TokenKindLParen), p.matchTokenKind(TokenKindLBracket):\n\t\treturn PrecedenceBracket\n\tcase p.matchTokenKind(TokenKindDash):\n\t\treturn PrecedenceDoubleColon\n\tcase p.matchTokenKind(TokenKindDot):\n\t\treturn PrecedenceDot\n\tcase p.matchKeyword(KeywordBetween), p.matchKeyword(KeywordLike), p.matchKeyword(KeywordIlike):\n\t\treturn PrecedenceBetweenLike\n\tcase p.matchKeyword(KeywordIn):\n\t\treturn precedenceIn\n\tcase p.matchKeyword(KeywordGlobal):\n\t\treturn PrecedenceGlobal\n\tcase p.matchTokenKind(TokenKindQuestionMark):\n\t\treturn PrecedenceQuery\n\tdefault:\n\t\treturn PrecedenceUnknown\n\t}\n}\n\nfunc (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindSingleEQ), p.matchTokenKind(TokenKindLT), p.matchTokenKind(TokenKindLE),\n\t\tp.matchTokenKind(TokenKindGE), p.matchTokenKind(TokenKindGT),\n\t\tp.matchTokenKind(TokenKindNE), p.matchTokenKind(\"<>\"),\n\t\tp.matchTokenKind(TokenKindMinus), p.matchTokenKind(TokenKindPlus), p.matchTokenKind(TokenKindMul),\n\t\tp.matchTokenKind(TokenKindDiv), p.matchTokenKind(TokenKindMod), p.matchTokenKind(TokenKindConcat),\n\t\tp.matchKeyword(KeywordIn), p.matchKeyword(KeywordLike),\n\t\tp.matchKeyword(KeywordIlike), p.matchKeyword(KeywordAnd), p.matchKeyword(KeywordOr),\n\t\tp.matchTokenKind(TokenKindArrow), p.matchTokenKind(TokenKindDoubleEQ):\n\t\top := p.last().ToString()\n\t\t_ = p.lexer.consumeToken()\n\t\trightExpr, err := p.parseSubExpr(p.Pos(), precedence)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &BinaryOperation{\n\t\t\tLeftExpr:  expr,\n\t\t\tOperation: TokenKind(op),\n\t\t\tRightExpr: rightExpr,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindDash):\n\t\t_ = p.lexer.consumeToken()\n\n\t\tif p.matchTokenKind(TokenKindIdent) && p.last().String == \"Tuple\" {\n\t\t\tname, err := p.parseIdent()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// it's a tuple type definition after \"::\" operator\n\t\t\trightExpr, err := p.parseNestedType(name, p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &BinaryOperation{\n\t\t\t\tLeftExpr:  expr,\n\t\t\t\tOperation: TokenKindDash,\n\t\t\t\tRightExpr: rightExpr,\n\t\t\t}, nil\n\t\t}\n\n\t\trightExpr, err := p.parseSubExpr(p.Pos(), precedence)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &BinaryOperation{\n\t\t\tLeftExpr:  expr,\n\t\t\tOperation: TokenKindDash,\n\t\t\tRightExpr: rightExpr,\n\t\t}, nil\n\tcase p.matchKeyword(KeywordBetween):\n\t\treturn p.parseBetweenClause(expr)\n\tcase p.matchKeyword(KeywordGlobal):\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.expectKeyword(KeywordIn) != nil {\n\t\t\treturn nil, fmt.Errorf(\"expected IN after GLOBAL, got %s\", p.lastTokenKind())\n\t\t}\n\t\trightExpr, err := p.parseSubExpr(p.Pos(), precedence)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &BinaryOperation{\n\t\t\tLeftExpr:  expr,\n\t\t\tOperation: \"GLOBAL IN\",\n\t\t\tRightExpr: rightExpr,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindDot):\n\t\t_ = p.lexer.consumeToken()\n\t\t// access column with dot notation\n\t\tvar rightExpr Expr\n\t\tvar err error\n\t\tif p.matchTokenKind(TokenKindIdent) {\n\t\t\trightExpr, err = p.parseIdent()\n\t\t} else {\n\t\t\trightExpr, err = p.parseDecimal(p.Pos())\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &IndexOperation{\n\t\t\tObject:    expr,\n\t\t\tOperation: TokenKindDot,\n\t\t\tIndex:     rightExpr,\n\t\t}, nil\n\tcase p.matchKeyword(KeywordNot):\n\t\t_ = p.lexer.consumeToken()\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordIn):\n\t\tcase p.matchKeyword(KeywordLike):\n\t\tcase p.matchKeyword(KeywordIlike):\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected IN, LIKE or ILIKE after NOT, got %s\", p.lastTokenKind())\n\t\t}\n\t\tif p.matchKeyword(KeywordBetween) {\n\t\t\treturn p.parseBetweenClause(expr)\n\t\t}\n\t\top := p.last().ToString()\n\t\t_ = p.lexer.consumeToken()\n\t\trightExpr, err := p.parseSubExpr(p.Pos(), precedence)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &BinaryOperation{\n\t\t\tLeftExpr:  expr,\n\t\t\tOperation: TokenKind(\"NOT \" + op),\n\t\t\tRightExpr: rightExpr,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindLBracket):\n\t\tparams, err := p.parseArrayParams(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &ObjectParams{\n\t\t\tObject: expr,\n\t\t\tParams: params,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindQuestionMark):\n\t\treturn p.parseTernaryExpr(expr)\n\tcase p.matchKeyword(KeywordIs):\n\t\t_ = p.lexer.consumeToken()\n\t\tisNotNull := p.tryConsumeKeywords(KeywordNot)\n\t\tif err := p.expectKeyword(KeywordNull); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif isNotNull {\n\t\t\treturn &IsNotNullExpr{\n\t\t\t\tIsPos: p.Pos(),\n\t\t\t\tExpr:  expr,\n\t\t\t}, nil\n\t\t}\n\t\treturn &IsNullExpr{\n\t\t\tIsPos: p.Pos(),\n\t\t\tExpr:  expr,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseExpr(pos Pos) (Expr, error) {\n\treturn p.parseSubExpr(pos, PrecedenceUnknown)\n}\n\nfunc (p *Parser) parseSubExpr(pos Pos, precedence int) (Expr, error) {\n\texpr, err := p.parseUnaryExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor !p.lexer.isEOF() {\n\t\tnextPrecedence := p.getNextPrecedence()\n\t\tif nextPrecedence <= precedence {\n\t\t\treturn expr, nil\n\t\t}\n\t\t// parse binary operation\n\t\texpr, err = p.parseInfix(expr, nextPrecedence)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn expr, nil\n}\n\nfunc (p *Parser) parseTernaryExpr(condition Expr) (*TernaryOperation, error) {\n\tif err := p.expectTokenKind(TokenKindQuestionMark); err != nil {\n\t\treturn nil, err\n\t}\n\ttrueExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectTokenKind(TokenKindColon); err != nil {\n\t\treturn nil, err\n\t}\n\tfalseExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &TernaryOperation{\n\t\tCondition: condition,\n\t\tTrueExpr:  trueExpr,\n\t\tFalseExpr: falseExpr,\n\t}, nil\n}\n\nfunc (p *Parser) parseExtractFrom(ident *Ident) (*IntervalFrom, error) {\n\tfromPos := p.Pos()\n\tif err := p.expectKeyword(KeywordFrom); err != nil {\n\t\treturn nil, err\n\t}\n\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &IntervalFrom{\n\t\tInterval: ident,\n\t\tFromPos:  fromPos,\n\t\tFromExpr: expr,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnExtractExpr(pos Pos) (*ExtractExpr, error) {\n\tif err := p.expectKeyword(KeywordExtract); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tparameters := make([]Expr, 0)\n\tfor !p.lexer.isEOF() {\n\t\texpr, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar param Expr\n\t\tif ident, ok := expr.(*Ident); ok {\n\t\t\tif intervalUnits.Contains(strings.ToUpper(ident.Name)) && p.matchKeyword(KeywordFrom) {\n\t\t\t\tparam, err = p.parseExtractFrom(ident)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tparameters = append(parameters, param)\n\t\t\t} else {\n\t\t\t\tparameters = append(parameters, expr)\n\t\t\t}\n\t\t} else {\n\t\t\tparameters = append(parameters, expr)\n\t\t}\n\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif len(parameters) == 0 {\n\t\treturn nil, fmt.Errorf(\"EXTRACT requires at least one parameter\")\n\t}\n\n\textractEnd := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ExtractExpr{\n\t\tExtractPos: pos,\n\t\tExtractEnd: extractEnd,\n\t\tParameters: parameters,\n\t}, nil\n}\n\nfunc (p *Parser) parseUnaryExpr(pos Pos) (Expr, error) {\n\top := p.last()\n\tswitch {\n\tcase p.matchTokenKind(TokenKindPlus),\n\t\tp.matchTokenKind(TokenKindMinus),\n\t\tp.matchKeyword(KeywordNot):\n\t\t_ = p.lexer.consumeToken()\n\tdefault:\n\t\treturn p.parseColumnExpr(pos)\n\t}\n\n\texpr, err := p.parseColumnExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &UnaryExpr{\n\t\tUnaryPos: pos,\n\t\tKind:     TokenKind(op.ToString()),\n\t\tExpr:     expr,\n\t}, nil\n\n}\n\nfunc (p *Parser) peekTokenKind(kind TokenKind) bool {\n\tif p.lexer.isEOF() {\n\t\treturn false\n\t}\n\ttoken, err := p.lexer.peekToken()\n\tif err != nil || token == nil {\n\t\treturn false\n\t}\n\treturn token.Kind == kind\n}\n\nfunc (p *Parser) peekKeyword(keyword string) bool {\n\tif p.lexer.isEOF() {\n\t\treturn false\n\t}\n\ttoken, err := p.lexer.peekToken()\n\tif err != nil || token == nil {\n\t\treturn false\n\t}\n\treturn token.Kind == TokenKindKeyword && strings.EqualFold(token.String, keyword)\n}\n\n// isSelectItemTerminatorKeyword checks whether the current token is a keyword\n// that begins a clause following the SELECT item list. When true, we should not\n// treat the keyword itself as a bare alias.\nfunc (p *Parser) isSelectItemTerminatorKeyword() bool {\n\tswitch {\n\tcase p.matchKeyword(KeywordFrom):\n\t\treturn true\n\tcase p.matchKeyword(KeywordWhere):\n\t\treturn true\n\tcase p.matchKeyword(KeywordPrewhere):\n\t\treturn true\n\tcase p.matchKeyword(KeywordGroup):\n\t\treturn true\n\tcase p.matchKeyword(KeywordHaving):\n\t\treturn true\n\tcase p.matchKeyword(KeywordWindow):\n\t\treturn true\n\tcase p.matchKeyword(KeywordOrder):\n\t\treturn true\n\tcase p.matchKeyword(KeywordLimit):\n\t\treturn true\n\tcase p.matchKeyword(KeywordOffset):\n\t\treturn true\n\tcase p.matchKeyword(KeywordSettings):\n\t\treturn true\n\tcase p.matchKeyword(KeywordFormat):\n\t\treturn true\n\tcase p.matchKeyword(KeywordUnion):\n\t\treturn true\n\tcase p.matchKeyword(KeywordExcept):\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (p *Parser) parseColumnExpr(pos Pos) (Expr, error) { //nolint:funlen\n\t// Should parse the keyword as an identifier if the keyword is followed by one of comma, `AS`.\n\t// For example: `SELECT 1 as interval GROUP BY interval` is a valid syntax in ClickHouse.\n\tif p.matchTokenKind(TokenKindKeyword) && (p.peekTokenKind(TokenKindComma) || p.peekKeyword(KeywordAs)) {\n\t\treturn p.parseIdent()\n\t}\n\tswitch {\n\tcase p.matchKeyword(KeywordInterval):\n\t\treturn p.parseInterval(true)\n\tcase p.matchKeyword(KeywordDate), p.matchKeyword(KeywordTimestamp):\n\t\tnextToken, err := p.lexer.peekToken()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif nextToken != nil && nextToken.Kind == TokenKindString {\n\t\t\treturn p.parseString(p.Pos())\n\t\t}\n\t\treturn p.parseIdentOrFunction(pos)\n\tcase p.matchKeyword(KeywordCast):\n\t\treturn p.parseColumnCastExpr(pos)\n\tcase p.matchKeyword(KeywordCase):\n\t\treturn p.parseColumnCaseExpr(pos)\n\tcase p.matchKeyword(KeywordSelect):\n\t\treturn p.parseSelectQuery(pos)\n\tcase p.matchKeyword(KeywordExtract):\n\t\treturn p.parseColumnExtractExpr(pos)\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\treturn p.parseIdentOrFunction(pos)\n\tcase p.matchTokenKind(TokenKindString): // string literal\n\t\treturn p.parseString(pos)\n\tcase p.matchTokenKind(TokenKindInt),\n\t\tp.matchTokenKind(TokenKindFloat): // number literal\n\t\treturn p.parseNumber(pos)\n\tcase p.matchTokenKind(TokenKindLParen):\n\t\tif peek, _ := p.lexer.peekToken(); peek != nil {\n\t\t\tif peek.Kind == TokenKindKeyword && strings.EqualFold(peek.String, KeywordSelect) {\n\t\t\t\treturn p.parseSubQuery(pos)\n\t\t\t}\n\t\t}\n\t\treturn p.parseFunctionParams(p.Pos())\n\tcase p.matchTokenKind(\"*\"):\n\t\treturn p.parseColumnStar(p.Pos())\n\tcase p.matchTokenKind(TokenKindLBracket):\n\t\treturn p.parseArrayParams(p.Pos())\n\tcase p.matchTokenKind(TokenKindLBrace):\n\t\t// The map literal string also starts with '{', so we need to check the next token\n\t\t// to determine if it is a map literal or a query param.\n\t\t// Treat both identifiers and keywords as identifier-like for placeholders.\n\t\t// parseIdent accepts keywords-as-ident, so this is safe.\n\t\tif p.peekTokenKind(TokenKindIdent) || p.peekTokenKind(TokenKindKeyword) {\n\t\t\treturn p.parseQueryParam(p.Pos())\n\t\t}\n\t\treturn p.parseMapLiteral(p.Pos())\n\tcase p.matchTokenKind(TokenKindDot):\n\t\treturn p.parseNumber(p.Pos())\n\tcase p.matchTokenKind(TokenKindQuestionMark):\n\t\t// Placeholder `?`\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &PlaceHolder{\n\t\t\tPlaceholderPos: pos,\n\t\t\tPlaceHolderEnd: pos,\n\t\t\tType:           string(TokenKindQuestionMark),\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseColumnCastExpr(pos Pos) (Expr, error) {\n\tif err := p.expectKeyword(KeywordCast); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumnExpr, err := p.parseColumnExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar separator string\n\tasPos := p.Pos()\n\tswitch {\n\t// CAST(x, T) and CAST(x AS T) are equivalent\n\tcase p.matchKeyword(KeywordAs), p.matchTokenKind(\",\"):\n\t\tseparator = p.last().String\n\t\t_ = p.lexer.consumeToken()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected AS or , but got %s\", p.lastTokenKind())\n\t}\n\n\tvar asColumnType Expr\n\t// CAST(1 AS 'Float') or CAST(1 AS Float) are equivalent\n\tif p.matchTokenKind(TokenKindString) {\n\t\tasColumnType, err = p.parseString(p.Pos())\n\t} else {\n\t\tasColumnType, err = p.parseColumnType(p.Pos())\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &CastExpr{\n\t\tCastPos:   pos,\n\t\tAsPos:     asPos,\n\t\tSeparator: separator,\n\t\tExpr:      columnExpr,\n\t\tAsType:    asColumnType,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnExprListWithLParen(pos Pos) (*ColumnExprList, error) {\n\treturn p.parseColumnExprListWithTerm(TokenKindRParen, pos)\n}\n\nfunc (p *Parser) parseColumnExprListWithSquareBracket(pos Pos) (*ColumnExprList, error) {\n\treturn p.parseColumnExprListWithTerm(TokenKindRBracket, pos)\n}\n\nfunc (p *Parser) parseColumnExprList(pos Pos) (*ColumnExprList, error) {\n\treturn p.parseColumnExprListWithTerm(\"\", pos)\n}\n\nfunc (p *Parser) parseColumnExprListWithTerm(term TokenKind, pos Pos) (*ColumnExprList, error) {\n\tcolumnExprList := &ColumnExprList{\n\t\tListPos: pos,\n\t\tListEnd: pos,\n\t}\n\tcolumnExprList.HasDistinct = p.tryConsumeKeywords(KeywordDistinct)\n\tcolumnList := make([]Expr, 0)\n\tfor !p.lexer.isEOF() || p.last() != nil {\n\t\tif term != \"\" && p.matchTokenKind(term) {\n\t\t\tbreak\n\t\t}\n\t\tcolumnExpr, err := p.parseColumnsExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif columnExpr == nil {\n\t\t\tbreak\n\t\t}\n\t\tcolumnList = append(columnList, columnExpr)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tcolumnExprList.Items = columnList\n\tif len(columnList) > 0 {\n\t\tcolumnExprList.ListEnd = columnList[len(columnList)-1].End()\n\t}\n\treturn columnExprList, nil\n}\n\nfunc (p *Parser) parseSelectItems() ([]*SelectItem, error) {\n\tselectItems := make([]*SelectItem, 0)\n\tfor !p.lexer.isEOF() || p.last() != nil {\n\t\tselectItem, err := p.parseSelectItem()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif selectItem == nil {\n\t\t\tbreak\n\t\t}\n\t\tselectItems = append(selectItems, selectItem)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn selectItems, nil\n}\n\nfunc (p *Parser) parseInterval(requireKeyword bool) (*IntervalExpr, error) {\n\tvar intervalPos Pos\n\tif requireKeyword {\n\t\tintervalPos = p.Pos()\n\t\tif err := p.expectKeyword(KeywordInterval); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tunit, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !intervalUnits.Contains(strings.ToUpper(unit.Name)) {\n\t\treturn nil, fmt.Errorf(\"unknown interval type: <%q>\", unit.Name)\n\t}\n\treturn &IntervalExpr{\n\t\tIntervalPos: intervalPos,\n\t\tExpr:        expr,\n\t\tUnit:        unit,\n\t}, nil\n}\n\nfunc (p *Parser) parseFunctionExpr(_ Pos) (*FunctionExpr, error) {\n\t// parse function name\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// parse function params\n\tparams, err := p.parseFunctionParams(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &FunctionExpr{\n\t\tName:   name,\n\t\tParams: params,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnArgList(pos Pos) (*ColumnArgList, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\tdistinct := p.tryConsumeKeywords(KeywordDistinct)\n\n\tvar items []Expr\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {\n\t\titem, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, item)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ColumnArgList{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tDistinct:      distinct,\n\t\tItems:         items,\n\t}, nil\n}\n\nfunc (p *Parser) parseFunctionParams(pos Pos) (*ParamExprList, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\tparams, err := p.parseColumnExprListWithLParen(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\tparamExprList := &ParamExprList{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tItems:         params,\n\t}\n\n\t// For some aggregate functions might support parametric arguments:\n\t// e.g. QUANTILE(0.5)(x) or QUANTILE(0.5, 0.9)(x).\n\t// So we need to have a check if there is another argument list with detecting the left bracket.\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\tcolumnArgList, err := p.parseColumnArgList(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tparamExprList.ColumnArgList = columnArgList\n\t}\n\treturn paramExprList, nil\n}\n\nfunc (p *Parser) parseMapLiteral(pos Pos) (*MapLiteral, error) {\n\tif err := p.expectTokenKind(TokenKindLBrace); err != nil {\n\t\treturn nil, err\n\t}\n\n\tkeyValues := make([]KeyValue, 0)\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRBrace) {\n\t\tkey, err := p.parseString(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := p.expectTokenKind(TokenKindColon); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkeyValues = append(keyValues, KeyValue{\n\t\t\tKey:   *key,\n\t\t\tValue: value,\n\t\t})\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\trightBracePos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRBrace); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MapLiteral{\n\t\tLBracePos: pos,\n\t\tRBracePos: rightBracePos,\n\t\tKeyValues: keyValues,\n\t}, nil\n}\n\nfunc (p *Parser) parseQueryParam(pos Pos) (*QueryParam, error) {\n\tif err := p.expectTokenKind(TokenKindLBrace); err != nil {\n\t\treturn nil, err\n\t}\n\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectTokenKind(TokenKindColon); err != nil {\n\t\treturn nil, err\n\t}\n\tcolumnType, err := p.parseColumnType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trightBracePos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRBrace); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &QueryParam{\n\t\tLBracePos: pos,\n\t\tRBracePos: rightBracePos,\n\t\tName:      ident,\n\t\tType:      columnType,\n\t}, nil\n}\n\nfunc (p *Parser) parseArrayParams(pos Pos) (*ArrayParamList, error) {\n\tif err := p.expectTokenKind(TokenKindLBracket); err != nil {\n\t\treturn nil, err\n\t}\n\tparams, err := p.parseColumnExprListWithSquareBracket(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trightBracketPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRBracket); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ArrayParamList{\n\t\tLeftBracketPos:  pos,\n\t\tRightBracketPos: rightBracketPos,\n\t\tItems:           params,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnsExpr(pos Pos) (*ColumnExpr, error) {\n\texpr, err := p.parseExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar alias *Ident\n\tif p.tryConsumeKeywords(KeywordAs) {\n\t\talias, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn &ColumnExpr{\n\t\tExpr:  expr,\n\t\tAlias: alias,\n\t}, nil\n}\n\nfunc (p *Parser) parseSelectItem() (*SelectItem, error) {\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmodifiers := make([]*FunctionExpr, 0)\n\tfor {\n\t\tif p.matchKeyword(KeywordExcept) || p.matchKeyword(KeywordApply) || p.matchKeyword(KeywordReplace) {\n\t\t\tmodifier, err := p.parseFunctionExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tmodifiers = append(modifiers, modifier)\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvar alias *Ident\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordAs):\n\t\talias, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase p.lastTokenKind() == TokenKindKeyword && !p.isSelectItemTerminatorKeyword():\n\t\talias, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tdefault:\n\t\talias = p.tryParseIdent()\n\t}\n\n\treturn &SelectItem{\n\t\tExpr:      expr,\n\t\tModifiers: modifiers,\n\t\tAlias:     alias,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnCaseExpr(pos Pos) (*CaseExpr, error) {\n\t// CASE expr\n\tcaseExpr := &CaseExpr{CasePos: pos}\n\tif err := p.expectKeyword(KeywordCase); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// case expr is optional\n\tif !p.matchKeyword(KeywordWhen) {\n\t\texpr, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcaseExpr.Expr = expr\n\t}\n\n\t// WHEN expr THEN expr\n\twhenClauses := make([]*WhenClause, 0)\n\tfor p.matchKeyword(KeywordWhen) {\n\t\twhenPos := p.Pos()\n\t\t_ = p.lexer.consumeToken()\n\t\twhenCondition, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tthenPos := p.Pos()\n\t\tif err := p.expectKeyword(KeywordThen); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tthenCondition, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\twhenClauses = append(whenClauses, &WhenClause{\n\t\t\tWhenPos: whenPos,\n\t\t\tThenPos: thenPos,\n\t\t\tWhen:    whenCondition,\n\t\t\tThen:    thenCondition,\n\t\t})\n\t}\n\tcaseExpr.Whens = whenClauses\n\n\t// ELSE expr\n\telsePos := p.Pos()\n\tif p.tryConsumeKeywords(KeywordElse) {\n\t\telseExpr, err := p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcaseExpr.ElsePos = elsePos\n\t\tcaseExpr.Else = elseExpr\n\t}\n\n\tif err := p.expectKeyword(KeywordEnd); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn caseExpr, nil\n}\n\nfunc (p *Parser) parseColumnType(_ Pos) (ColumnType, error) {\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p.parseColumnTypeArgs(ident)\n}\n\nfunc (p *Parser) parseColumnTypeArgs(ident *Ident) (ColumnType, error) { // nolint:funlen\n\tif lParen := p.tryConsumeTokenKind(TokenKindLParen); lParen != nil {\n\t\tswitch {\n\t\tcase p.matchTokenKind(TokenKindIdent):\n\t\t\tswitch {\n\t\t\tcase strings.EqualFold(ident.Name, \"Nested\"):\n\t\t\t\treturn p.parseNestedType(ident, p.Pos())\n\t\t\tcase strings.EqualFold(ident.Name, \"JSON\"):\n\t\t\t\treturn p.parseJSONType(ident, p.Pos())\n\t\t\tcase strings.EqualFold(ident.Name, \"QBit\"):\n\t\t\t\treturn p.parseColumnTypeWithParams(ident, p.Pos())\n\t\t\tcase strings.EqualFold(ident.Name, \"Tuple\"):\n\t\t\t\treturn p.parseNestedType(ident, p.Pos())\n\t\t\tdefault:\n\t\t\t\treturn p.parseComplexType(ident, p.Pos())\n\t\t\t}\n\t\tcase p.matchTokenKind(TokenKindString):\n\t\t\tif peekToken, err := p.lexer.peekToken(); err == nil && peekToken.Kind == TokenKindSingleEQ {\n\t\t\t\t// enum values\n\t\t\t\treturn p.parseEnumType(ident, p.Pos())\n\t\t\t}\n\t\t\t// like Datetime('Asia/Dubai')\n\t\t\treturn p.parseColumnTypeWithParams(ident, p.Pos())\n\t\tcase p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat):\n\t\t\t// fixed size\n\t\t\treturn p.parseColumnTypeWithParams(ident, p.Pos())\n\t\tcase p.matchTokenKind(TokenKindRParen):\n\t\t\trightParenPos := p.Pos()\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\treturn &TypeWithParams{\n\t\t\t\tName:          ident,\n\t\t\t\tLeftParenPos:  lParen.Pos,\n\t\t\t\tRightParenPos: rightParenPos,\n\t\t\t}, nil\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unexpected token kind: %v\", p.lastTokenKind())\n\t\t}\n\t}\n\treturn &ScalarType{Name: ident}, nil\n}\n\nfunc (p *Parser) parseColumnPropertyType(_ Pos) (Expr, error) {\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &PropertyType{\n\t\tName: ident,\n\t}, nil\n}\n\nfunc (p *Parser) parseComplexType(name *Ident, pos Pos) (*ComplexType, error) {\n\tsubTypes := make([]ColumnType, 0)\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {\n\t\tsubExpr, err := p.parseColumnType(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsubTypes = append(subTypes, subExpr)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ComplexType{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tName:          name,\n\t\tParams:        subTypes,\n\t}, nil\n}\n\nfunc (p *Parser) parseEnumType(name *Ident, pos Pos) (*EnumType, error) {\n\tenumType := &EnumType{\n\t\tName:    name,\n\t\tListPos: pos,\n\t\tValues:  make([]EnumValue, 0),\n\t}\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {\n\t\tenumValue, err := p.parseEnumValueExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif enumValue == nil {\n\t\t\tbreak\n\t\t}\n\t\tenumType.Values = append(enumType.Values, *enumValue)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tif len(enumType.Values) > 0 {\n\t\tenumType.ListEnd = enumType.Values[len(enumType.Values)-1].Value.NumEnd\n\t}\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn enumType, nil\n}\n\nfunc (p *Parser) parseColumnTypeWithParams(name *Ident, pos Pos) (*TypeWithParams, error) {\n\tparams := make([]Literal, 0)\n\tparam, err := p.parseLiteral(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tparams = append(params, param)\n\tfor !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tsize, err := p.parseLiteral(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tparams = append(params, size)\n\t}\n\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &TypeWithParams{\n\t\tName:          name,\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tParams:        params,\n\t}, nil\n}\n\nfunc (p *Parser) parseJSONPath() (*JSONPath, error) {\n\tidents := make([]*Ident, 0)\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tidents = append(idents, ident)\n\n\tfor !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindDot) != nil {\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tidents = append(idents, ident)\n\t}\n\treturn &JSONPath{\n\t\tIdents: idents,\n\t}, nil\n}\n\nfunc (p *Parser) parseJSONMaxDynamicOptions(pos Pos) (*JSONOption, error) {\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch ident.Name {\n\tcase \"max_dynamic_types\":\n\t\tnumber, err := p.parseNumber(pos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &JSONOption{MaxDynamicTypes: number}, nil\n\tcase \"max_dynamic_paths\":\n\t\tnumber, err := p.parseNumber(pos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &JSONOption{MaxDynamicPaths: number}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseJSONOption() (*JSONOption, error) {\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordSkip):\n\t\tif p.tryConsumeKeywords(KeywordRegexp) {\n\t\t\tregex, err := p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &JSONOption{\n\t\t\t\tSkipRegex: regex,\n\t\t\t}, nil\n\t\t}\n\t\tjsonPath, err := p.parseJSONPath()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &JSONOption{\n\t\t\tSkipPath: jsonPath,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\t// Could be max_dynamic_* option OR a type hint like: a.b String\n\t\t// Lookahead to see if there's an '=' following the identifier path (max_dynamic_*)\n\t\t// or if it's a path followed by a ColumnType.\n\t\t// We'll parse a JSONPath first, then decide.\n\t\t// Save lexer state by consuming as path greedily using existing helpers.\n\t\t// Try: if single ident and next is '=' -> max_dynamic_*; else treat as path + type\n\n\t\t// Peek next token after current ident without consuming type; we need to\n\t\t// attempt to parse as max_dynamic_* first as it's existing behavior for a single ident.\n\t\t// To support dotted paths, we need to capture path, then if '=' exists, it's option; otherwise parse type.\n\t\tpath, err := p.parseJSONPath()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif p.tryConsumeTokenKind(TokenKindSingleEQ) != nil {\n\t\t\t// This is a max_dynamic_* option; only valid when path is a single ident of that name\n\t\t\t// Reconstruct handling similar to parseJSONMaxDynamicOptions but we already consumed ident and '='\n\t\t\t// Determine which option based on the first ident name\n\t\t\tif len(path.Idents) != 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t\t\t}\n\t\t\tname := path.Idents[0].Name\n\t\t\tswitch name {\n\t\t\tcase \"max_dynamic_types\":\n\t\t\t\tnumber, err := p.parseNumber(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn &JSONOption{MaxDynamicTypes: number}, nil\n\t\t\tcase \"max_dynamic_paths\":\n\t\t\t\tnumber, err := p.parseNumber(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn &JSONOption{MaxDynamicPaths: number}, nil\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t\t\t}\n\t\t}\n\t\t// Otherwise, expect a ColumnType as a type hint for the JSON subpath\n\t\tcolType, err := p.parseColumnType(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &JSONOption{Column: &JSONTypeHint{Path: path, Type: colType}}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseJSONType(name *Ident, pos Pos) (*JSONType, error) {\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\treturn &JSONType{Name: name}, nil\n\t}\n\n\toptions := make([]*JSONOption, 0)\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {\n\t\toption, err := p.parseJSONOption()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\toptions = append(options, option)\n\t\tif p.tryConsumeTokenKind(\",\") == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &JSONType{\n\t\tName: name,\n\t\tOptions: &JSONOptions{\n\t\t\tLParen: pos,\n\t\t\tRParen: rightParenPos,\n\t\t\tItems:  options,\n\t\t},\n\t}, nil\n}\n\nfunc (p *Parser) parseNestedType(name *Ident, pos Pos) (*NestedType, error) {\n\tcolumns, err := p.parseNestedTypeFields()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &NestedType{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tName:          name,\n\t\tColumns:       columns,\n\t}, nil\n}\n\nfunc (p *Parser) parseNestedTypeFields() ([]Expr, error) {\n\tswitch {\n\tcase p.lexer.isEOF() || p.matchTokenKind(TokenKindRParen):\n\t\t// Cases like `Tuple()`\n\t\treturn []Expr{}, nil\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif p.matchTokenKind(TokenKindIdent) {\n\t\t\t// Cases like `Tuple(a Int, b String)` or `Nested(a Int, b String)`\n\t\t\treturn p.parseNestedTypeFieldsWithNames(ident)\n\t\t}\n\n\t\t// Cases like `Tuple(Int, String)`\n\t\treturn p.parseNestedTypeFieldsWithoutNames(ident)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token kind: %s\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseNestedTypeFieldsWithNames(columnName *Ident) ([]Expr, error) {\n\tcolumns := make([]Expr, 0)\n\n\tcolumnType, err := p.parseColumnType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumns = append(columns, &ColumnDef{\n\t\tNamePos: columnName.Pos(),\n\t\tName: &NestedIdentifier{\n\t\t\tIdent: columnName,\n\t\t},\n\t\tType:      columnType,\n\t\tColumnEnd: columnType.End(),\n\t})\n\n\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\treturn columns, nil\n\t}\n\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {\n\t\tcolumn, err := p.parseNestedTypeFieldWithName()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif column == nil {\n\t\t\tbreak\n\t\t}\n\t\tcolumns = append(columns, column)\n\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn columns, nil\n}\n\nfunc (p *Parser) parseNestedTypeFieldsWithoutNames(columnType *Ident) ([]Expr, error) {\n\tcolumns := make([]Expr, 0)\n\n\tcolumn, err := p.parseColumnTypeArgs(columnType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumns = append(columns, column)\n\n\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\treturn columns, nil\n\t}\n\n\tfor !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {\n\t\tcolumn, err := p.parseColumnType(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif column == nil {\n\t\t\tbreak\n\t\t}\n\t\tcolumns = append(columns, column)\n\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn columns, nil\n}\n\nfunc (p *Parser) parseNestedTypeFieldWithName() (Expr, error) {\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumnType, err := p.parseColumnType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &ColumnDef{\n\t\tNamePos: name.Pos(),\n\t\tName: &NestedIdentifier{\n\t\t\tIdent: name,\n\t\t},\n\t\tType:      columnType,\n\t\tColumnEnd: columnType.End(),\n\t}, nil\n}\n\nfunc (p *Parser) tryParseCompressionCodecs(pos Pos) (*CompressionCodec, error) {\n\tif !p.tryConsumeKeywords(KeywordCodec) {\n\t\treturn nil, nil // nolint\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse codec name\n\tcodecType, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// parse DELTA if  CODEC(Delta, ZSTD(1))\n\t// or CODEC(Delta(9), ZSTD(1)) or CODEC(T64, ZSTD(1))\n\tvar name *Ident\n\tvar typeLevel *NumberLiteral\n\tswitch strings.ToUpper(codecType.Name) {\n\tcase \"DELTA\", \"DOUBLEDELTA\", \"T64\", \"GORILLA\":\n\t\t// try parse delta level\n\t\ttypeLevel, err = p.tryParseCompressionLevel(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif p.matchTokenKind(TokenKindComma) {\n\t\t\tif err := p.expectTokenKind(TokenKindComma); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tname, err = p.parseIdent()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\tcase \"ZSTD\", \"LZ4HC\", \"LH4\":\n\t\t// For compression codecs, try to parse level\n\t\ttypeLevel, err = p.tryParseCompressionLevel(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar level *NumberLiteral\n\t// TODO: check if the codec name is valid\n\tif name != nil {\n\t\tswitch strings.ToUpper(name.Name) {\n\t\tcase \"ZSTD\", \"LZ4HC\", \"LH4\":\n\t\t\tlevel, err = p.tryParseCompressionLevel(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\n\trightParenPos := p.End()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// If there's only one codec (no second name), store it in Name field instead of Type\n\t// This handles cases like CODEC(DoubleDelta) or CODEC(ZSTD(1))\n\tif name == nil {\n\t\treturn &CompressionCodec{\n\t\t\tCodecPos:      pos,\n\t\t\tRightParenPos: rightParenPos,\n\t\t\tType:          nil,\n\t\t\tTypeLevel:     nil,\n\t\t\tName:          codecType,\n\t\t\tLevel:         typeLevel,\n\t\t}, nil\n\t}\n\n\t// Two codecs: Type is the preprocessing codec, Name is the compression codec\n\t// e.g., CODEC(DoubleDelta, ZSTD(1))\n\treturn &CompressionCodec{\n\t\tCodecPos:      pos,\n\t\tRightParenPos: rightParenPos,\n\t\tType:          codecType,\n\t\tTypeLevel:     typeLevel,\n\t\tName:          name,\n\t\tLevel:         level,\n\t}, nil\n}\n\nfunc (p *Parser) parseEnumValueExpr(pos Pos) (*EnumValue, error) {\n\tname, err := p.parseString(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalue, err := p.parseNumber(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &EnumValue{\n\t\tName:  name,\n\t\tValue: value,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnStar(pos Pos) (*Ident, error) {\n\tif err := p.expectTokenKind(\"*\"); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Ident{\n\t\tNamePos: pos,\n\t\tNameEnd: pos,\n\t\tName:    \"*\",\n\t}, nil\n}\n\nfunc (p *Parser) tryParseCompressionLevel(pos Pos) (*NumberLiteral, error) {\n\tif p.tryConsumeTokenKind(TokenKindLParen) == nil {\n\t\treturn nil, nil // nolint\n\t}\n\n\tnum, err := p.parseNumber(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn num, nil\n}\n"
  },
  {
    "path": "parser/parser_common.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype Parser struct {\n\tlexer *Lexer\n}\n\nfunc NewParser(buffer string) *Parser {\n\treturn &Parser{\n\t\tlexer: NewLexer(buffer),\n\t}\n}\n\nfunc (p *Parser) lastTokenKind() TokenKind {\n\tif p.last() == nil {\n\t\treturn TokenKindEOF\n\t}\n\treturn p.last().Kind\n}\n\nfunc (p *Parser) last() *Token {\n\treturn p.lexer.lastToken\n}\n\nfunc (p *Parser) End() Pos {\n\tif p.last() == nil {\n\t\treturn Pos(p.lexer.current + 1)\n\t}\n\treturn p.last().End\n}\n\nfunc (p *Parser) Pos() Pos {\n\tlast := p.last()\n\tif last == nil {\n\t\treturn Pos(p.lexer.current)\n\t}\n\treturn last.Pos\n}\n\nfunc (p *Parser) matchTokenKind(kind TokenKind) bool {\n\treturn p.lastTokenKind() == kind ||\n\t\t(kind == TokenKindIdent && p.lastTokenKind() == TokenKindKeyword)\n}\n\n// expectTokenKind consumes the last token if it is the given kind.\nfunc (p *Parser) expectTokenKind(kind TokenKind) error {\n\tif lastToken := p.tryConsumeTokenKind(kind); lastToken != nil {\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"expected the last token kind is: %s, but got %s\", kind, p.lastTokenKind())\n}\n\nfunc (p *Parser) tryConsumeTokenKind(kind TokenKind) *Token {\n\tif p.matchTokenKind(kind) {\n\t\tlastToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\treturn lastToken\n\t}\n\treturn nil\n}\n\nfunc (p *Parser) matchKeyword(keyword string) bool {\n\treturn p.matchTokenKind(TokenKindKeyword) && strings.EqualFold(p.last().String, keyword)\n}\n\nfunc (p *Parser) matchOneOfKeywords(keywords ...string) bool {\n\tfor _, keyword := range keywords {\n\t\tif p.matchKeyword(keyword) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *Parser) expectKeyword(keyword string) error {\n\tif !p.matchKeyword(keyword) {\n\t\treturn fmt.Errorf(\"expected keyword: %s, but got %s\", keyword, p.lastTokenKind())\n\t}\n\t_ = p.lexer.consumeToken()\n\treturn nil\n}\n\nfunc (p *Parser) tryConsumeKeywords(keywords ...string) bool {\n\tsavedState := p.lexer.saveState()\n\tfor _, keyword := range keywords {\n\t\tif !p.matchKeyword(keyword) {\n\t\t\tp.lexer.restoreState(savedState)\n\t\t\treturn false\n\t\t}\n\t\t_ = p.lexer.consumeToken()\n\t}\n\treturn true\n}\n\nfunc (p *Parser) tryParseIdent() *Ident {\n\tif p.lastTokenKind() != TokenKindIdent {\n\t\treturn nil\n\t}\n\tlastToken := p.last()\n\t_ = p.lexer.consumeToken()\n\treturn &Ident{\n\t\tNamePos:   lastToken.Pos,\n\t\tNameEnd:   lastToken.End,\n\t\tName:      lastToken.String,\n\t\tQuoteType: lastToken.QuoteType,\n\t}\n}\n\nfunc (p *Parser) parseIdent() (*Ident, error) {\n\tlastToken := p.last()\n\tif err := p.expectTokenKind(TokenKindIdent); err != nil {\n\t\treturn nil, err\n\t}\n\tident := &Ident{\n\t\tNamePos:   lastToken.Pos,\n\t\tNameEnd:   lastToken.End,\n\t\tName:      lastToken.String,\n\t\tQuoteType: lastToken.QuoteType,\n\t}\n\treturn ident, nil\n}\n\nfunc (p *Parser) parseIdentOrStar() (*Ident, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\treturn p.parseIdent()\n\tcase p.matchTokenKind(\"*\"):\n\t\tlastToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &Ident{\n\t\t\tNamePos: lastToken.Pos,\n\t\t\tNameEnd: lastToken.End,\n\t\t\tName:    lastToken.String,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected <ident> or *, but got %q\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseIdentOrString() (*Ident, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\treturn p.parseIdent()\n\tcase p.matchTokenKind(TokenKindString):\n\t\tlastToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\treturn &Ident{\n\t\t\tNamePos:   lastToken.Pos,\n\t\t\tNameEnd:   lastToken.End,\n\t\t\tName:      lastToken.String,\n\t\t\tQuoteType: SingleQuote, // Treat string literals as single-quoted identifiers\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected <ident> or <string>, but got %q\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) tryParseDotIdent(_ Pos) (*Ident, error) {\n\tif p.tryConsumeTokenKind(TokenKindDot) == nil {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseIdent()\n}\n\nfunc (p *Parser) tryParseDotIdentOrString(_ Pos) (*Ident, error) {\n\tif p.tryConsumeTokenKind(TokenKindDot) == nil {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseIdentOrString()\n}\n\nfunc (p *Parser) parseUUID() (*UUID, error) {\n\tif err := p.expectKeyword(KeywordUuid); err != nil {\n\t\treturn nil, err\n\t}\n\n\tuuidString, err := p.parseString(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &UUID{\n\t\tValue: uuidString,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseUUID() (*UUID, error) {\n\tif !p.matchKeyword(KeywordUuid) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseUUID()\n}\n\nfunc (p *Parser) tryParseComment() (*StringLiteral, error) {\n\tif !p.tryConsumeKeywords(KeywordComment) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseString(p.Pos())\n}\n\nfunc (p *Parser) tryParseIfExists() (bool, error) {\n\tif !p.tryConsumeKeywords(KeywordIf) {\n\t\treturn false, nil\n\t}\n\n\tif err := p.expectKeyword(KeywordExists); err != nil {\n\t\treturn false, err\n\t}\n\treturn true, nil\n}\n\nfunc (p *Parser) tryParseIfNotExists() (bool, error) {\n\tif !p.tryConsumeKeywords(KeywordIf) {\n\t\treturn false, nil\n\t}\n\n\tif err := p.expectKeyword(KeywordNot); err != nil {\n\t\treturn false, err\n\t}\n\n\tif err := p.expectKeyword(KeywordExists); err != nil {\n\t\treturn false, err\n\t}\n\treturn true, nil\n}\n\nfunc (p *Parser) tryParseNull(pos Pos) *NullLiteral {\n\tif !p.tryConsumeKeywords(KeywordNull) {\n\t\treturn nil\n\t}\n\treturn &NullLiteral{NullPos: pos}\n}\n\nfunc (p *Parser) tryParseNotNull(pos Pos) (*NotNullLiteral, error) {\n\tif !p.tryConsumeKeywords(KeywordNot) {\n\t\treturn nil, nil // nolint\n\t}\n\tnotNull := &NotNullLiteral{NotPos: pos}\n\n\tnullPos := p.Pos()\n\tif err := p.expectKeyword(KeywordNull); err != nil {\n\t\treturn notNull, err\n\t}\n\tnotNull.NullLiteral = &NullLiteral{NullPos: nullPos}\n\treturn notNull, nil\n}\n\nfunc (p *Parser) parseDecimal(pos Pos) (*NumberLiteral, error) {\n\tnumber, err := p.parseNumber(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif number.Base != 10 {\n\t\treturn nil, fmt.Errorf(\"invalid decimal literal: %q\", number.Literal)\n\t}\n\treturn number, nil\n}\n\nfunc (p *Parser) parseNumber(pos Pos) (*NumberLiteral, error) {\n\tvar err error\n\n\tlastToken := p.last()\n\tswitch {\n\tcase p.matchTokenKind(TokenKindInt):\n\t\terr = p.expectTokenKind(TokenKindInt)\n\tcase p.matchTokenKind(TokenKindFloat):\n\t\terr = p.expectTokenKind(TokenKindFloat)\n\tcase p.matchTokenKind(TokenKindDot):\n\t\t_ = p.lexer.consumeToken()\n\t\tlastToken = p.last()\n\t\tif err := p.expectTokenKind(TokenKindInt); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif lastToken.Base != 10 {\n\t\t\treturn nil, fmt.Errorf(\"invalid decimal literal: %q\", lastToken.String)\n\t\t}\n\t\tlastToken.String = \".\" + lastToken.String\n\t\tlastToken.Kind = TokenKindFloat\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected <int> or <float>, but got %q\", p.lastTokenKind())\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnumber := &NumberLiteral{\n\t\tNumPos:  pos,\n\t\tNumEnd:  lastToken.End,\n\t\tLiteral: lastToken.String,\n\t\tBase:    lastToken.Base,\n\t}\n\treturn number, nil\n}\n\nfunc (p *Parser) parseString(pos Pos) (*StringLiteral, error) {\n\tlastToken := p.last()\n\tif err := p.expectTokenKind(TokenKindString); err != nil {\n\t\treturn nil, err\n\t}\n\n\tstr := &StringLiteral{\n\t\tLiteralPos: pos,\n\t\tLiteralEnd: lastToken.End,\n\t\tLiteral:    lastToken.String,\n\t}\n\treturn str, nil\n}\n\nfunc (p *Parser) parseLiteral(pos Pos) (Literal, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat):\n\t\treturn p.parseNumber(pos)\n\tcase p.matchTokenKind(TokenKindString):\n\t\treturn p.parseString(pos)\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\treturn p.parseIdent()\n\tcase p.matchKeyword(KeywordNull):\n\t\t// accept the NULL keyword\n\t\treturn &NullLiteral{NullPos: pos}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected <int>, <string>, <ident> or keyword <NULL>, but got %q\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) ParseNestedIdentifier(pos Pos) (*NestedIdentifier, error) {\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdotIdent, err := p.tryParseDotIdent(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif dotIdent != nil {\n\t\treturn &NestedIdentifier{\n\t\t\tIdent:    ident,\n\t\t\tDotIdent: dotIdent,\n\t\t}, nil\n\t}\n\treturn &NestedIdentifier{\n\t\tIdent: ident,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseFormat(pos Pos) (*FormatClause, error) {\n\tif !p.matchKeyword(KeywordFormat) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseFormat(pos)\n}\n\nfunc (p *Parser) parseFormat(pos Pos) (*FormatClause, error) {\n\tif err := p.expectKeyword(KeywordFormat); err != nil {\n\t\treturn nil, err\n\t}\n\tformatIdent, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &FormatClause{\n\t\tFormatPos: pos,\n\t\tFormat:    formatIdent,\n\t}, nil\n}\n\nfunc (p *Parser) wrapError(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\n\tlineNo := 0\n\tcolumn := 0\n\n\tfor i := 0; i < int(p.Pos()); i++ {\n\t\tif p.lexer.input[i] == '\\n' {\n\t\t\tlineNo++\n\t\t\tcolumn = 0\n\t\t} else {\n\t\t\tcolumn++\n\t\t}\n\t}\n\n\tlines := strings.Split(p.lexer.input, \"\\n\")\n\tvar buf strings.Builder\n\tbuf.WriteString(fmt.Sprintf(\"line %d:%d %s\\n\", lineNo, column, err.Error()))\n\tfor i, line := range lines {\n\t\tif i == lineNo {\n\t\t\tbuf.WriteString(line)\n\t\t\tbuf.WriteByte('\\n')\n\t\t\tfor j := 0; j < column; j++ {\n\t\t\t\tbuf.WriteByte(' ')\n\t\t\t}\n\t\t\tif p.last() != nil {\n\t\t\t\tbuf.WriteString(strings.Repeat(\"^\", len(p.last().String)))\n\t\t\t} else {\n\t\t\t\tbuf.WriteString(\"^\")\n\t\t\t}\n\t\t\tbuf.WriteByte('\\n')\n\t\t}\n\t}\n\treturn errors.New(buf.String())\n}\n\nfunc (p *Parser) parseRatioExpr(pos Pos) (*RatioExpr, error) {\n\tnumerator, err := p.parseNumber(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar denominator *NumberLiteral\n\tif p.tryConsumeTokenKind(TokenKindDiv) != nil {\n\t\tdenominator, err = p.parseNumber(pos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn &RatioExpr{\n\t\tNumerator:   numerator,\n\t\tDenominator: denominator,\n\t}, nil\n}\n"
  },
  {
    "path": "parser/parser_drop.go",
    "content": "package parser\n\nfunc (p *Parser) parseDropDatabase(pos Pos) (*DropDatabase, error) {\n\tif err := p.expectKeyword(KeywordDatabase); err != nil {\n\t\treturn nil, err\n\t}\n\n\tisExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstatementEnd := name.End()\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif onCluster != nil {\n\t\tstatementEnd = onCluster.End()\n\t}\n\n\treturn &DropDatabase{\n\t\tDropPos:      pos,\n\t\tName:         name,\n\t\tIfExists:     isExists,\n\t\tOnCluster:    onCluster,\n\t\tStatementEnd: statementEnd,\n\t}, nil\n}\n\nfunc (p *Parser) parseDropStmt(pos Pos) (*DropStmt, error) {\n\tvar isTemporary bool\n\tdropTarget := KeywordTable\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordDictionary):\n\t\tdropTarget = KeywordDictionary\n\tcase p.tryConsumeKeywords(KeywordView):\n\t\tdropTarget = KeywordView\n\tdefault:\n\t\tisTemporary = p.tryConsumeKeywords(KeywordTemporary)\n\t\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tisExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmodifier, err := p.tryParseModifier()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DropStmt{\n\t\tDropPos:      pos,\n\t\tDropTarget:   dropTarget,\n\t\tName:         name,\n\t\tIfExists:     isExists,\n\t\tOnCluster:    onCluster,\n\t\tIsTemporary:  isTemporary,\n\t\tModifier:     modifier,\n\t\tStatementEnd: p.Pos(),\n\t}, nil\n}\n\nfunc (p *Parser) tryParseModifier() (string, error) {\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordSync):\n\t\treturn \"SYNC\", nil\n\tcase p.tryConsumeKeywords(KeywordNo):\n\t\tif err := p.expectKeyword(KeywordDelay); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn \"NO DELAY\", nil\n\t}\n\treturn \"\", nil\n}\n"
  },
  {
    "path": "parser/parser_query.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"slices\"\n)\n\nfunc (p *Parser) tryParseWithClause(pos Pos) (*WithClause, error) {\n\tif !p.matchKeyword(KeywordWith) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseWithClause(pos)\n}\n\nfunc (p *Parser) parseWithClause(pos Pos) (*WithClause, error) {\n\tif err := p.expectKeyword(KeywordWith); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcteExpr, err := p.parseCTEStmt(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tctes := []*CTEStmt{cteExpr}\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tcteExpr, err := p.parseCTEStmt(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tctes = append(ctes, cteExpr)\n\t}\n\n\treturn &WithClause{\n\t\tWithPos: pos,\n\t\tCTEs:    ctes,\n\t\tEndPos:  ctes[len(ctes)-1].End(),\n\t}, nil\n}\n\nfunc (p *Parser) tryParseTopClause(pos Pos) (*TopClause, error) {\n\tif !p.matchKeyword(KeywordTop) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseTopClause(pos)\n}\n\nfunc (p *Parser) parseTopClause(pos Pos) (*TopClause, error) {\n\tif err := p.expectKeyword(KeywordTop); err != nil {\n\t\treturn nil, err\n\t}\n\n\tnumber, err := p.parseNumber(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttopEnd := number.End()\n\n\twithTies := false\n\tif p.tryConsumeKeywords(KeywordWith) {\n\t\ttopEnd = p.End()\n\t\tif err := p.expectKeyword(KeywordTies); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\twithTies = true\n\t}\n\treturn &TopClause{\n\t\tTopPos:   pos,\n\t\tTopEnd:   topEnd,\n\t\tNumber:   number,\n\t\tWithTies: withTies,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseDistinctOn(pos Pos) (*DistinctOn, error) {\n\tif !p.matchKeyword(KeywordOn) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseDistinctOn(pos)\n}\n\nfunc (p *Parser) parseDistinctOn(pos Pos) (*DistinctOn, error) {\n\tif err := p.expectKeyword(KeywordOn); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcol, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tidents := []*NestedIdentifier{col}\n\n\tfor p.matchTokenKind(TokenKindComma) {\n\t\t_ = p.lexer.consumeToken()\n\n\t\tcol, err = p.ParseNestedIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tidents = append(idents, col)\n\t}\n\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DistinctOn{\n\t\tIdents:        idents,\n\t\tDistinctOnPos: pos,\n\t\tDistinctOnEnd: p.Pos(),\n\t}, nil\n}\n\nfunc (p *Parser) tryParseFromClause(pos Pos) (*FromClause, error) {\n\tif !p.matchKeyword(KeywordFrom) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseFromClause(pos)\n}\n\nfunc (p *Parser) parseFromClause(pos Pos) (*FromClause, error) {\n\tif err := p.expectKeyword(KeywordFrom); err != nil {\n\t\treturn nil, err\n\t}\n\n\texpr, err := p.parseJoinExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &FromClause{\n\t\tFromPos: pos,\n\t\tExpr:    expr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseJoinConstraints(pos Pos) (Expr, error) {\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordOn):\n\t\tcolumnExprList, err := p.parseColumnExprList(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &OnClause{\n\t\t\tOnPos: pos,\n\t\t\tOn:    columnExprList,\n\t\t}, nil\n\tcase p.tryConsumeKeywords(KeywordUsing):\n\t\thasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil\n\t\tcolumnExprList, err := p.parseColumnExprListWithLParen(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif hasParen {\n\t\t\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn &UsingClause{\n\t\t\tUsingPos: pos,\n\t\t\tUsing:    columnExprList,\n\t\t}, nil\n\t}\n\treturn nil, nil\n}\n\nfunc (p *Parser) parseJoinOp(_ Pos) []string {\n\tvar modifiers []string\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordCross): // cross join\n\t\tmodifiers = append(modifiers, KeywordCross)\n\tcase p.matchKeyword(KeywordAny), p.matchKeyword(KeywordAll):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.matchKeyword(KeywordFull) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\t\tif p.matchKeyword(KeywordLeft) || p.matchKeyword(KeywordRight) || p.matchKeyword(KeywordInner) || p.matchKeyword(KeywordOuter) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\tcase p.matchKeyword(KeywordSemi), p.matchKeyword(KeywordAsof):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.matchKeyword(KeywordLeft) || p.matchKeyword(KeywordRight) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\t\tif p.matchKeyword(KeywordOuter) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\tcase p.matchKeyword(KeywordInner):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.matchKeyword(KeywordAll) || p.matchKeyword(KeywordAny) || p.matchKeyword(KeywordAsof) || p.matchKeyword(KeywordArray) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\tcase p.matchKeyword(KeywordLeft):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.matchKeyword(KeywordOuter) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\t\tif p.matchKeyword(KeywordSemi) || p.matchKeyword(KeywordAnti) ||\n\t\t\tp.matchKeyword(KeywordAny) || p.matchKeyword(KeywordAll) ||\n\t\t\tp.matchKeyword(KeywordAsof) || p.matchKeyword(KeywordArray) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\tcase p.matchKeyword(KeywordRight):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.matchKeyword(KeywordOuter) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\t\tif p.matchKeyword(KeywordSemi) || p.matchKeyword(KeywordAnti) ||\n\t\t\tp.matchKeyword(KeywordAny) || p.matchKeyword(KeywordAll) ||\n\t\t\tp.matchKeyword(KeywordAsof) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\tcase p.matchKeyword(KeywordFull):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t\tif p.matchKeyword(KeywordOuter) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\t\tif p.matchKeyword(KeywordAll) || p.matchKeyword(KeywordAny) {\n\t\t\tmodifiers = append(modifiers, p.last().String)\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\tcase p.matchKeyword(KeywordArray):\n\t\tmodifiers = append(modifiers, p.last().String)\n\t\t_ = p.lexer.consumeToken()\n\t}\n\treturn modifiers\n}\n\nfunc (p *Parser) parseJoinTableExpr(_ Pos) (Expr, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent), p.matchTokenKind(TokenKindString), p.matchTokenKind(TokenKindLParen):\n\t\ttableExpr, err := p.parseTableExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstatementEnd := tableExpr.End()\n\n\t\thasFinal := p.matchKeyword(KeywordFinal)\n\t\tif hasFinal {\n\t\t\tstatementEnd = p.End()\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\n\t\tsampleRatio, err := p.tryParseSampleClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif sampleRatio != nil {\n\t\t\tstatementEnd = sampleRatio.End()\n\t\t}\n\t\treturn &JoinTableExpr{\n\t\t\tTable:        tableExpr,\n\t\t\tSampleRatio:  sampleRatio,\n\t\t\tHasFinal:     hasFinal,\n\t\t\tStatementEnd: statementEnd,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected table name or subquery, got %s\", fmt.Sprintf(\"%v\", p.lastTokenKind()))\n\t}\n}\n\nfunc (p *Parser) parseJoinRightExpr(pos Pos) (expr Expr, err error) {\n\tvar rightExpr Expr\n\tvar modifiers []string\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordGlobal):\n\tcase p.tryConsumeKeywords(KeywordLocal):\n\tcase p.tryConsumeTokenKind(TokenKindComma) != nil:\n\t\treturn p.parseJoinExpr(p.Pos())\n\tdefault:\n\t\tmodifiers = p.parseJoinOp(p.Pos())\n\t}\n\n\tif len(modifiers) != 0 && !p.matchKeyword(KeywordJoin) {\n\t\treturn nil, fmt.Errorf(\"expected JOIN, got %s\", p.lastTokenKind())\n\t}\n\tif !p.tryConsumeKeywords(KeywordJoin) {\n\t\treturn nil, nil\n\t}\n\n\tmodifiers = append(modifiers, KeywordJoin)\n\n\t// Check if this is an ARRAY JOIN\n\tif slices.Contains(modifiers, KeywordArray) {\n\t\t// For ARRAY JOIN, parse column expression list instead of table expression\n\t\texpr, err = p.parseColumnExprList(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// ARRAY JOIN doesn't have constraints (ON/USING)\n\t\t// try parse next join\n\t\trightExpr, err = p.parseJoinRightExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &JoinExpr{\n\t\t\tJoinPos:     pos,\n\t\t\tLeft:        expr,\n\t\t\tRight:       rightExpr,\n\t\t\tModifiers:   modifiers,\n\t\t\tConstraints: nil,\n\t\t}, nil\n\t}\n\n\texpr, err = p.parseJoinTableExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconstrains, err := p.tryParseJoinConstraints(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// try parse next join\n\trightExpr, err = p.parseJoinRightExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &JoinExpr{\n\t\tJoinPos:     pos,\n\t\tLeft:        expr,\n\t\tRight:       rightExpr,\n\t\tModifiers:   modifiers,\n\t\tConstraints: constrains,\n\t}, nil\n}\n\nfunc (p *Parser) parseJoinExpr(pos Pos) (expr Expr, err error) {\n\tif expr, err = p.parseJoinTableExpr(p.Pos()); err != nil {\n\t\treturn nil, err\n\t}\n\trightExpr, err := p.parseJoinRightExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif rightExpr == nil {\n\t\treturn expr, nil\n\t}\n\treturn &JoinExpr{\n\t\tJoinPos: pos,\n\t\tLeft:    expr,\n\t\tRight:   rightExpr,\n\t}, nil\n}\n\nfunc (p *Parser) parseTableExpr(pos Pos) (*TableExpr, error) {\n\tvar expr Expr\n\tvar err error\n\tswitch {\n\tcase p.matchTokenKind(TokenKindString), p.matchTokenKind(TokenKindIdent):\n\t\t// table name\n\t\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// it's a table name\n\t\tif tableIdentifier.Database != nil || !p.matchTokenKind(TokenKindLParen) { // database.table\n\t\t\texpr = tableIdentifier\n\t\t} else {\n\t\t\t// table function expr\n\t\t\ttableArgs, err := p.parseTableArgList(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\texpr = &TableFunctionExpr{\n\t\t\t\tName: tableIdentifier.Table,\n\t\t\t\tArgs: tableArgs,\n\t\t\t}\n\t\t}\n\tcase p.matchTokenKind(TokenKindLParen):\n\t\texpr, err = p.parseSubQuery(p.Pos())\n\tdefault:\n\t\treturn nil, errors.New(\"expect table name or subquery\")\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableEnd := expr.End()\n\tif p.tryConsumeKeywords(KeywordAs) {\n\t\talias, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texpr = &AliasExpr{\n\t\t\tExpr:     expr,\n\t\t\tAliasPos: alias.Pos(),\n\t\t\tAlias:    alias,\n\t\t}\n\t\ttableEnd = expr.End()\n\t} else if p.matchTokenKind(TokenKindIdent) && p.lastTokenKind() != TokenKindKeyword {\n\t\talias, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texpr = &AliasExpr{\n\t\t\tExpr:     expr,\n\t\t\tAliasPos: alias.Pos(),\n\t\t\tAlias:    alias,\n\t\t}\n\t\ttableEnd = expr.End()\n\t}\n\n\tisFinalExist := false\n\tif p.tryConsumeKeywords(KeywordFinal) {\n\t\tswitch expr.(type) {\n\t\tcase *TableFunctionExpr:\n\t\t\treturn nil, errors.New(\"table function doesn't support FINAL\")\n\t\tcase *SelectQuery:\n\t\t\treturn nil, errors.New(\"subquery doesn't support FINAL\")\n\t\t}\n\t\tisFinalExist = true\n\t\ttableEnd = expr.End()\n\t}\n\n\treturn &TableExpr{\n\t\tTablePos: pos,\n\t\tTableEnd: tableEnd,\n\t\tExpr:     expr,\n\t\tHasFinal: isFinalExist,\n\t}, nil\n}\n\nfunc (p *Parser) tryParsePrewhereClause(pos Pos) (*PrewhereClause, error) {\n\tif !p.matchKeyword(KeywordPrewhere) {\n\t\treturn nil, nil\n\t}\n\treturn p.parsePrewhereClause(pos)\n}\nfunc (p *Parser) parsePrewhereClause(pos Pos) (*PrewhereClause, error) {\n\tif err := p.expectKeyword(KeywordPrewhere); err != nil {\n\t\treturn nil, err\n\t}\n\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &PrewhereClause{\n\t\tPrewherePos: pos,\n\t\tExpr:        expr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseWhereClause(pos Pos) (*WhereClause, error) {\n\tif !p.matchKeyword(KeywordWhere) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseWhereClause(pos)\n}\n\nfunc (p *Parser) parseWhereClause(pos Pos) (*WhereClause, error) {\n\tif err := p.expectKeyword(KeywordWhere); err != nil {\n\t\treturn nil, err\n\t}\n\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WhereClause{\n\t\tWherePos: pos,\n\t\tExpr:     expr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseGroupByClause(pos Pos) (*GroupByClause, error) {\n\tif !p.matchKeyword(KeywordGroup) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseGroupByClause(pos)\n}\n\n// syntax: groupByClause? (WITH (CUBE | ROLLUP))? (WITH TOTALS)?\nfunc (p *Parser) parseGroupByClause(pos Pos) (*GroupByClause, error) {\n\tif err := p.expectKeyword(KeywordGroup); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar expr Expr\n\tvar err error\n\taggregateType := \"\"\n\tswitch {\n\tcase p.matchKeyword(KeywordCube) || p.matchKeyword(KeywordRollup):\n\t\taggregateType = p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\texpr, err = p.parseFunctionParams(p.Pos())\n\tcase p.tryConsumeKeywords(KeywordGrouping, KeywordSets):\n\t\taggregateType = \"GROUPING SETS\"\n\t\texpr, err = p.parseFunctionParams(p.Pos())\n\tcase p.tryConsumeKeywords(KeywordAll):\n\t\taggregateType = \"ALL\"\n\tdefault:\n\t\texpr, err = p.parseColumnExprListWithLParen(p.Pos())\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgroupBy := &GroupByClause{\n\t\tGroupByPos:    pos,\n\t\tAggregateType: aggregateType,\n\t\tExpr:          expr,\n\t}\n\n\t// parse WITH CUBE, ROLLUP, TOTALS\n\tfor p.tryConsumeKeywords(KeywordWith) {\n\t\tswitch {\n\t\tcase p.tryConsumeKeywords(KeywordCube):\n\t\t\tgroupBy.WithCube = true\n\t\tcase p.tryConsumeKeywords(KeywordRollup):\n\t\t\tgroupBy.WithRollup = true\n\t\tcase p.tryConsumeKeywords(KeywordTotals):\n\t\t\tgroupBy.WithTotals = true\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected CUBE, ROLLUP or TOTALS, got %s\", p.lastTokenKind())\n\t\t}\n\t}\n\tgroupBy.GroupByEnd = p.Pos()\n\n\treturn groupBy, nil\n}\n\nfunc (p *Parser) tryParseLimitAfterLimitByClause(pos Pos) (*LimitClause, error) {\n\tif !p.matchKeyword(KeywordLimit) {\n\t\treturn nil, nil\n\t}\n\n\treturn p.parseLimitClause(pos)\n}\n\nfunc (p *Parser) tryParseLimitClause(pos Pos) (*LimitClause, error) {\n\tif !p.matchKeyword(KeywordLimit) && !p.matchKeyword(KeywordOffset) {\n\t\treturn nil, nil\n\t}\n\n\treturn p.parseLimitClause(pos)\n}\n\nfunc (p *Parser) parseLimitClause(pos Pos) (*LimitClause, error) {\n\tvar limit Expr\n\tvar offset Expr\n\tvar err error\n\tif p.tryConsumeKeywords(KeywordLimit) {\n\t\tlimit, err = p.parseExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif p.tryConsumeKeywords(KeywordOffset) {\n\t\t\toffset, err = p.parseExpr(p.Pos())\n\t\t} else if p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\t\toffset = limit\n\t\t\tlimit, err = p.parseExpr(p.Pos())\n\t\t}\n\t} else if p.tryConsumeKeywords(KeywordOffset) {\n\t\toffset, err = p.parseExpr(p.Pos())\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &LimitClause{\n\t\tLimitPos: pos,\n\t\tLimit:    limit,\n\t\tOffset:   offset,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseLimitByClause(pos Pos) (Expr, error) {\n\tif !p.matchKeyword(KeywordLimit) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseLimitByClause(pos)\n}\n\nfunc (p *Parser) parseBetweenClause(expr Expr) (*BetweenClause, error) {\n\tif err := p.expectKeyword(KeywordBetween); err != nil {\n\t\treturn nil, err\n\t}\n\n\tbetweenExpr, err := p.parseSubExpr(p.Pos(), PrecedenceBetweenLike)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tandPos := p.Pos()\n\tif err := p.expectKeyword(KeywordAnd); err != nil {\n\t\treturn nil, err\n\t}\n\n\tandExpr, err := p.parseSubExpr(p.Pos(), PrecedenceBetweenLike)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &BetweenClause{\n\t\tExpr:    expr,\n\t\tBetween: betweenExpr,\n\t\tAndPos:  andPos,\n\t\tAnd:     andExpr,\n\t}, nil\n}\n\nfunc (p *Parser) parseLimitByClause(pos Pos) (Expr, error) {\n\tlimit, err := p.parseLimitClause(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar by *ColumnExprList\n\tif !p.tryConsumeKeywords(KeywordBy) {\n\t\treturn limit, nil\n\t}\n\tif by, err = p.parseColumnExprListWithLParen(p.Pos()); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &LimitByClause{\n\t\tLimit:  limit,\n\t\tByExpr: by,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseWindowFrameClause(pos Pos) (*WindowFrameClause, error) {\n\tif !p.matchKeyword(KeywordRows) && !p.matchKeyword(KeywordRange) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseWindowFrameClause(pos)\n}\n\nfunc (p *Parser) parseWindowFrameClause(pos Pos) (*WindowFrameClause, error) {\n\tvar windowFrameType string\n\tif p.matchKeyword(KeywordRows) || p.matchKeyword(KeywordRange) {\n\t\twindowFrameType = p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t} else {\n\t\treturn nil, fmt.Errorf(\"expected ROWS or RANGE for window frame\")\n\t}\n\n\tvar expr Expr\n\tif p.tryConsumeKeywords(KeywordBetween) {\n\t\tleft, err := p.parseFrameExtent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tandPos := p.Pos()\n\t\tif err := p.expectKeyword(KeywordAnd); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tright, err := p.parseFrameExtent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texpr = &BetweenClause{\n\t\t\tBetween: left,\n\t\t\tAndPos:  andPos,\n\t\t\tAnd:     right,\n\t\t}\n\t} else {\n\t\t// single extent\n\t\textent, err := p.parseFrameExtent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texpr = extent\n\t}\n\n\treturn &WindowFrameClause{\n\t\tFramePos: pos,\n\t\tType:     windowFrameType,\n\t\tExtend:   expr,\n\t}, nil\n}\n\n// parseFrameExtent parses a single frame extent\nfunc (p *Parser) parseFrameExtent() (Expr, error) {\n\tswitch {\n\tcase p.matchKeyword(KeywordCurrent):\n\t\treturn p.parseFrameCurrentRow()\n\tcase p.matchKeyword(KeywordUnbounded):\n\t\treturn p.parseFrameUnbounded()\n\tcase p.matchTokenKind(TokenKindInt):\n\t\treturn p.parseFrameNumber()\n\tcase p.matchTokenKind(TokenKindLBrace):\n\t\treturn p.parseFrameParam()\n\tcase p.matchKeyword(KeywordInterval):\n\t\treturn p.parseFrameInterval()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected UNBOUNDED, CURRENT ROW, integer, parameter, or interval\")\n\t}\n}\n\nfunc (p *Parser) parseFrameCurrentRow() (Expr, error) {\n\tcurrentPos := p.Pos()\n\t_ = p.lexer.consumeToken()\n\tif err := p.expectKeyword(KeywordRow); err != nil {\n\t\treturn nil, err\n\t}\n\trowEnd := p.End()\n\treturn &WindowFrameCurrentRow{\n\t\tCurrentPos: currentPos,\n\t\tRowEnd:     rowEnd,\n\t}, nil\n}\n\nfunc (p *Parser) parseFrameUnbounded() (Expr, error) {\n\tunboundedPos := p.Pos()\n\t_ = p.lexer.consumeToken()\n\n\tdirection, err := p.parseFrameDirection()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WindowFrameUnbounded{\n\t\tUnboundedPos: unboundedPos,\n\t\tDirection:    direction,\n\t}, nil\n}\n\nfunc (p *Parser) parseFrameNumber() (Expr, error) {\n\tnumber, err := p.parseNumber(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdirection, endPos, err := p.parseFrameDirectionWithEnd()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WindowFrameNumber{\n\t\tEndPos:    endPos,\n\t\tNumber:    number,\n\t\tDirection: direction,\n\t}, nil\n}\n\nfunc (p *Parser) parseFrameParam() (Expr, error) {\n\tqueryParam, err := p.parseQueryParam(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdirection, endPos, err := p.parseFrameDirectionWithEnd()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WindowFrameParam{\n\t\tParam:     queryParam,\n\t\tEndPos:    endPos,\n\t\tDirection: direction,\n\t}, nil\n}\n\nfunc (p *Parser) parseFrameInterval() (Expr, error) {\n\tintervalExpr, err := p.parseInterval(true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdirection, endPos, err := p.parseFrameDirectionWithEnd()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WindowFrameExtendExpr{\n\t\tExpr:      intervalExpr,\n\t\tDirection: direction,\n\t\tEndPos:    endPos,\n\t}, nil\n}\n\nfunc (p *Parser) parseFrameDirection() (string, error) {\n\tswitch {\n\tcase p.matchKeyword(KeywordPreceding), p.matchKeyword(KeywordFollowing):\n\t\tdirection := p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t\treturn direction, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"expected PRECEDING or FOLLOWING, got %s\", p.lastTokenKind())\n\t}\n}\n\nfunc (p *Parser) parseFrameDirectionWithEnd() (string, Pos, error) {\n\tif !p.matchKeyword(KeywordPreceding) && !p.matchKeyword(KeywordFollowing) {\n\t\treturn \"\", 0, fmt.Errorf(\"expected PRECEDING or FOLLOWING, got %s\", p.lastTokenKind())\n\t}\n\tendPos := p.End()\n\tdirection := p.last().String\n\t_ = p.lexer.consumeToken()\n\treturn direction, endPos, nil\n}\n\nfunc (p *Parser) tryParseWindowClause(pos Pos) (*WindowClause, error) {\n\tif !p.matchKeyword(KeywordWindow) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseWindowClause(pos)\n}\n\nfunc (p *Parser) parseWindowCondition(pos Pos) (*WindowExpr, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\tvar windowName *Ident\n\tif p.canParseWindowNameInParens() {\n\t\tvar err error\n\t\twindowName, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tpartitionBy, err := p.tryParsePartitionByClause(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\torderBy, err := p.tryParseOrderByClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tframe, err := p.tryParseWindowFrameClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WindowExpr{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tWindowName:    windowName,\n\t\tPartitionBy:   partitionBy,\n\t\tOrderBy:       orderBy,\n\t\tFrame:         frame,\n\t}, nil\n}\n\nfunc (p *Parser) canParseWindowNameInParens() bool {\n\tif !p.matchTokenKind(TokenKindIdent) {\n\t\treturn false\n\t}\n\tif !p.matchTokenKind(TokenKindKeyword) {\n\t\treturn true\n\t}\n\n\tsavedState := p.lexer.saveState()\n\tdefer p.lexer.restoreState(savedState)\n\n\tswitch {\n\tcase p.matchKeyword(KeywordPartition), p.matchKeyword(KeywordOrder):\n\t\t_ = p.lexer.consumeToken()\n\t\treturn !p.matchKeyword(KeywordBy)\n\tcase p.matchKeyword(KeywordRows), p.matchKeyword(KeywordRange):\n\t\t_ = p.lexer.consumeToken()\n\t\treturn !p.matchKeyword(KeywordBetween) &&\n\t\t\t!p.matchKeyword(KeywordCurrent) &&\n\t\t\t!p.matchKeyword(KeywordUnbounded) &&\n\t\t\t!p.matchTokenKind(TokenKindInt) &&\n\t\t\t!p.matchTokenKind(TokenKindLBrace) &&\n\t\t\t!p.matchKeyword(KeywordInterval)\n\tdefault:\n\t\treturn true\n\t}\n}\n\nfunc (p *Parser) parseWindowClause(pos Pos) (*WindowClause, error) {\n\tif err := p.expectKeyword(KeywordWindow); err != nil {\n\t\treturn nil, err\n\t}\n\n\twindows := make([]*WindowDefinition, 0, 1)\n\tfor {\n\t\twindowName, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tasPos := p.Pos()\n\t\tif err := p.expectKeyword(KeywordAs); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcondition, err := p.parseWindowCondition(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\twindows = append(windows, &WindowDefinition{\n\t\t\tName:  windowName,\n\t\t\tAsPos: asPos,\n\t\t\tExpr:  condition,\n\t\t})\n\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvar endPos Pos\n\tif len(windows) > 0 {\n\t\tendPos = windows[len(windows)-1].End()\n\t}\n\n\treturn &WindowClause{\n\t\tWindowPos: pos,\n\t\tEndPos:    endPos,\n\t\tWindows:   windows,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseHavingClause(pos Pos) (*HavingClause, error) {\n\tif !p.matchKeyword(KeywordHaving) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseHavingClause(pos)\n}\n\nfunc (p *Parser) parseHavingClause(pos Pos) (*HavingClause, error) {\n\tif err := p.expectKeyword(KeywordHaving); err != nil {\n\t\treturn nil, err\n\t}\n\n\texpr, err := p.parseColumnsExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &HavingClause{\n\t\tHavingPos: pos,\n\t\tExpr:      expr,\n\t}, nil\n}\n\nfunc (p *Parser) parseSubQuery(_ Pos) (*SubQuery, error) {\n\n\thasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil\n\n\tselectQuery, err := p.parseSelectQuery(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif hasParen {\n\t\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &SubQuery{\n\t\tHasParen: hasParen,\n\t\tSelect:   selectQuery,\n\t}, nil\n}\n\nfunc (p *Parser) parseSelectQuery(_ Pos) (*SelectQuery, error) {\n\tif !p.matchKeyword(KeywordSelect) && !p.matchKeyword(KeywordWith) && !p.matchTokenKind(TokenKindLParen) {\n\t\treturn nil, fmt.Errorf(\"expected SELECT, WITH or (, got %s\", p.lastTokenKind())\n\t}\n\n\thasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil\n\tselectStmt, err := p.parseSelectStmt(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordUnion):\n\t\tswitch {\n\t\tcase p.tryConsumeKeywords(KeywordAll):\n\t\t\tunionAllExpr, err := p.parseSelectQuery(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tselectStmt.UnionAll = unionAllExpr\n\t\tcase p.tryConsumeKeywords(KeywordDistinct):\n\t\t\tunionDistinctExpr, err := p.parseSelectQuery(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tselectStmt.UnionDistinct = unionDistinctExpr\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected ALL or DISTINCT, got %s\", p.lastTokenKind())\n\t\t}\n\tcase p.tryConsumeKeywords(KeywordExcept):\n\t\texceptExpr, err := p.parseSelectQuery(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tselectStmt.Except = exceptExpr\n\t}\n\tif hasParen {\n\t\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn selectStmt, nil\n}\n\nfunc (p *Parser) parseSelectStmt(pos Pos) (*SelectQuery, error) { // nolint: funlen\n\twithClause, err := p.tryParseWithClause(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordSelect); err != nil {\n\t\treturn nil, err\n\t}\n\t// DISTINCT?\n\thasDistinct := p.tryConsumeKeywords(KeywordDistinct)\n\tdistinctOn, err := p.tryParseDistinctOn(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttop, err := p.tryParseTopClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tselectItems, err := p.parseSelectItems()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstatementEnd := pos\n\tif len(selectItems) > 0 {\n\t\tstatementEnd = selectItems[len(selectItems)-1].End()\n\t}\n\tfrom, err := p.tryParseFromClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif from != nil {\n\t\tstatementEnd = from.End()\n\t}\n\tprewhere, err := p.tryParsePrewhereClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif prewhere != nil {\n\t\tstatementEnd = prewhere.End()\n\t}\n\twhere, err := p.tryParseWhereClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif where != nil {\n\t\tstatementEnd = where.End()\n\t}\n\tgroupBy, err := p.tryParseGroupByClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif groupBy != nil {\n\t\tstatementEnd = groupBy.End()\n\t}\n\twithTotal := false\n\tlastPos := p.Pos()\n\tif p.tryConsumeKeywords(KeywordWith) {\n\t\tif err := p.expectKeyword(KeywordTotals); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\twithTotal = true\n\t\tstatementEnd = lastPos\n\t}\n\thaving, err := p.tryParseHavingClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif having != nil {\n\t\tstatementEnd = having.End()\n\t}\n\twindow, err := p.tryParseWindowClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif window != nil {\n\t\tstatementEnd = window.End()\n\t}\n\torderBy, err := p.tryParseOrderByClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif orderBy != nil {\n\t\tstatementEnd = orderBy.End()\n\t}\n\n\tvar limitBy *LimitByClause\n\tvar limit *LimitClause\n\tparsedLimitBy, err := p.tryParseLimitByClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif parsedLimitBy != nil {\n\t\tstatementEnd = parsedLimitBy.End()\n\t\tswitch e := parsedLimitBy.(type) {\n\t\tcase *LimitByClause:\n\t\t\tlimitBy = e\n\t\t\tlimit, err = p.tryParseLimitAfterLimitByClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif limit != nil {\n\t\t\t\tstatementEnd = limit.End()\n\t\t\t}\n\t\tcase *LimitClause:\n\t\t\tlimit = e\n\t\t}\n\t} else {\n\t\tlimit, err = p.tryParseLimitClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif limit != nil {\n\t\t\tstatementEnd = limit.End()\n\t\t}\n\t}\n\n\tsettings, err := p.tryParseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif settings != nil {\n\t\tstatementEnd = settings.End()\n\t}\n\n\tformat, err := p.tryParseFormat(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif format != nil {\n\t\tstatementEnd = format.End()\n\t}\n\n\treturn &SelectQuery{\n\t\tWith:         withClause,\n\t\tSelectPos:    pos,\n\t\tStatementEnd: statementEnd,\n\t\tTop:          top,\n\t\tHasDistinct:  hasDistinct,\n\t\tDistinctOn:   distinctOn,\n\t\tSelectItems:  selectItems,\n\t\tFrom:         from,\n\t\tWindow:       window,\n\t\tPrewhere:     prewhere,\n\t\tWhere:        where,\n\t\tGroupBy:      groupBy,\n\t\tHaving:       having,\n\t\tOrderBy:      orderBy,\n\t\tLimitBy:      limitBy,\n\t\tLimit:        limit,\n\t\tSettings:     settings,\n\t\tFormat:       format,\n\t\tWithTotal:    withTotal,\n\t}, nil\n}\n\nfunc (p *Parser) parseCTEStmt(pos Pos) (*CTEStmt, error) {\n\texpr, err := p.parseExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordAs); err != nil {\n\t\treturn nil, err\n\t}\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\tselectQuery, err := p.parseSelectQuery(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &CTEStmt{\n\t\t\tCTEPos: pos,\n\t\t\tExpr:   expr,\n\t\t\tAlias:  selectQuery,\n\t\t}, nil\n\t}\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &CTEStmt{\n\t\tCTEPos: pos,\n\t\tExpr:   expr,\n\t\tAlias:  name,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseSampleClause(pos Pos) (*SampleClause, error) {\n\tif !p.matchKeyword(KeywordSample) {\n\t\treturn nil, nil\n\t}\n\treturn p.parseSampleClause(pos)\n}\n\nfunc (p *Parser) parseSampleClause(pos Pos) (*SampleClause, error) {\n\tif err := p.expectKeyword(KeywordSample); err != nil {\n\t\treturn nil, err\n\t}\n\tratio, err := p.parseRatioExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar offset *RatioExpr\n\tif p.matchKeyword(KeywordOffset) {\n\t\t_ = p.lexer.consumeToken()\n\t\toffset, err = p.parseRatioExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &SampleClause{\n\t\tSamplePos: pos,\n\t\tRatio:     ratio,\n\t\tOffset:    offset,\n\t}, nil\n}\n\nfunc (p *Parser) parseExplainStmt(pos Pos) (*ExplainStmt, error) {\n\tif err := p.expectKeyword(KeywordExplain); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar explainType string\n\tswitch {\n\tcase p.matchKeyword(KeywordSyntax),\n\t\tp.matchKeyword(KeywordPipeline),\n\t\tp.matchKeyword(KeywordEstimate),\n\t\tp.matchKeyword(KeywordAst):\n\t\texplainType = p.last().String\n\t\t_ = p.lexer.consumeToken()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected SYNTAX, PIPELINE, ESTIMATE or AST, got %s\", p.lastTokenKind())\n\t}\n\tstmt, err := p.parseSelectQuery(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ExplainStmt{\n\t\tExplainPos: pos,\n\t\tType:       explainType,\n\t\tStatement:  stmt,\n\t}, nil\n}\n"
  },
  {
    "path": "parser/parser_table.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nfunc (p *Parser) parseDDL(pos Pos) (DDL, error) {\n\tswitch {\n\tcase p.matchKeyword(KeywordCreate),\n\t\tp.matchKeyword(KeywordAttach):\n\t\t_ = p.lexer.consumeToken()\n\t\torReplace := p.tryConsumeKeywords(KeywordOr, KeywordReplace)\n\t\tif orReplace && !p.matchOneOfKeywords(KeywordTemporary, KeywordTable, KeywordView, KeywordFunction, KeywordDictionary) {\n\t\t\treturn nil, fmt.Errorf(\"expected keyword: TEMPORARY|TABLE|VIEW|FUNCTION|DICTIONARY, but got %q\", p.last().String)\n\t\t}\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordNamed):\n\t\t\treturn p.parseCreateNamedCollection(pos)\n\t\tcase p.matchKeyword(KeywordDatabase):\n\t\t\treturn p.parseCreateDatabase(pos)\n\t\tcase p.matchKeyword(KeywordDictionary):\n\t\t\treturn p.parseCreateDictionary(pos, orReplace)\n\t\tcase p.matchKeyword(KeywordTable),\n\t\t\tp.matchKeyword(KeywordTemporary):\n\t\t\treturn p.parseCreateTable(pos, orReplace)\n\t\tcase p.matchKeyword(KeywordFunction):\n\t\t\treturn p.parseCreateFunction(pos, orReplace)\n\t\tcase p.matchKeyword(KeywordMaterialized):\n\t\t\treturn p.parseCreateMaterializedView(pos)\n\t\tcase p.matchKeyword(KeywordLive):\n\t\t\treturn p.parseCreateLiveView(pos)\n\t\tcase p.matchKeyword(KeywordView):\n\t\t\treturn p.parseCreateView(pos, orReplace)\n\t\tcase p.matchKeyword(KeywordRole):\n\t\t\treturn p.parseCreateRole(pos)\n\t\tcase p.matchKeyword(KeywordUser):\n\t\t\treturn p.parseCreateUser(pos)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected keyword: NAMED|DATABASE|DICTIONARY|TABLE|VIEW|ROLE|USER|FUNCTION|MATERIALIZED, but got %q\",\n\t\t\t\tp.lastTokenKind())\n\t\t}\n\tcase p.matchKeyword(KeywordAlter):\n\t\t_ = p.lexer.consumeToken()\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordRole):\n\t\t\treturn p.parseAlterRole(pos)\n\t\tcase p.matchKeyword(KeywordTable):\n\t\t\treturn p.parseAlterTable(pos)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected keyword: TABLE|ROLE, but got %q\", p.last().String)\n\t\t}\n\tcase p.matchKeyword(KeywordDrop),\n\t\tp.matchKeyword(KeywordDetach):\n\t\t_ = p.lexer.consumeToken()\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordDatabase):\n\t\t\treturn p.parseDropDatabase(pos)\n\t\tcase p.matchKeyword(KeywordTemporary),\n\t\t\tp.matchKeyword(KeywordView),\n\t\t\tp.matchKeyword(KeywordDictionary),\n\t\t\tp.matchKeyword(KeywordTable):\n\t\t\treturn p.parseDropStmt(pos)\n\t\tcase p.matchKeyword(KeywordUser),\n\t\t\tp.matchKeyword(KeywordRole):\n\t\t\treturn p.parserDropUserOrRole(pos)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected keyword: DATABASE|TABLE, but got %q\", p.last().String)\n\t\t}\n\tcase p.matchKeyword(KeywordTruncate):\n\t\treturn p.parseTruncateTable(pos)\n\tcase p.matchKeyword(KeywordRename):\n\t\treturn p.parseRenameStmt(pos)\n\t}\n\treturn nil, nil // nolint\n}\n\nfunc (p *Parser) parseCreateDatabase(pos Pos) (*CreateDatabase, error) {\n\tif err := p.expectKeyword(KeywordDatabase); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// try to parse IF NOT EXISTS clause\n\tifNotExists, err := p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// parse database name\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tStatementEnd := name.End()\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif onCluster != nil {\n\t\tStatementEnd = onCluster.End()\n\t}\n\tengineExpr, err := p.tryParseEngineExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif engineExpr != nil {\n\t\tStatementEnd = engineExpr.End()\n\t}\n\tcommentExpr, err := p.tryParseComment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &CreateDatabase{\n\t\tCreatePos:    pos,\n\t\tStatementEnd: StatementEnd,\n\t\tName:         name,\n\t\tIfNotExists:  ifNotExists,\n\t\tOnCluster:    onCluster,\n\t\tEngine:       engineExpr,\n\t\tComment:      commentExpr,\n\t}, nil\n}\n\nfunc (p *Parser) parseCreateDictionary(pos Pos, orReplace bool) (*CreateDictionary, error) {\n\tif err := p.expectKeyword(KeywordDictionary); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreateDict := &CreateDictionary{\n\t\tCreatePos: pos,\n\t\tOrReplace: orReplace,\n\t}\n\n\t// parse IF NOT EXISTS clause if exists\n\tvar err error\n\tcreateDict.IfNotExists, err = p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse dictionary name\n\tname, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateDict.Name = name\n\n\t// try parse UUID clause if exists\n\tuuid, err := p.tryParseUUID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateDict.UUID = uuid\n\n\t// parse ON CLUSTER clause if exists\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateDict.OnCluster = onCluster\n\n\t// parse dictionary schema clause (required)\n\tschema, err := p.parseDictionarySchemaClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateDict.Schema = schema\n\n\t// parse dictionary engine clause (required)\n\tengine, err := p.parseDictionaryEngineClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateDict.Engine = engine\n\tcreateDict.StatementEnd = engine.End()\n\n\t// parse COMMENT clause if exists\n\tcomment, err := p.tryParseComment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateDict.Comment = comment\n\tif comment != nil {\n\t\tcreateDict.StatementEnd = comment.End()\n\t}\n\n\treturn createDict, nil\n}\n\nfunc (p *Parser) parseCreateNamedCollection(pos Pos) (*CreateNamedCollection, error) {\n\tif err := p.expectKeyword(KeywordNamed); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordCollection); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreateCollection := &CreateNamedCollection{\n\t\tCreatePos: pos,\n\t}\n\n\t// parse IF NOT EXISTS clause if exists\n\tvar err error\n\tcreateCollection.IfNotExists, err = p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse collection name\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateCollection.Name = name\n\n\t// parse ON CLUSTER clause if exists\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateCollection.OnCluster = onCluster\n\n\t// parse AS keyword\n\tif err := p.expectKeyword(KeywordAs); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse parameters\n\tparams := make([]*NamedCollectionParam, 0)\n\tfor !p.lexer.isEOF() {\n\t\tparam, err := p.parseNamedCollectionParam(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tparams = append(params, param)\n\n\t\t// Check if there's another parameter\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tcreateCollection.Params = params\n\n\tif len(params) > 0 {\n\t\tcreateCollection.StatementEnd = params[len(params)-1].End()\n\t} else if onCluster != nil {\n\t\tcreateCollection.StatementEnd = onCluster.End()\n\t} else {\n\t\tcreateCollection.StatementEnd = name.End()\n\t}\n\n\treturn createCollection, nil\n}\n\nfunc (p *Parser) parseNamedCollectionParam(pos Pos) (*NamedCollectionParam, error) {\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Parse the value - can be string, number, or identifier\n\tvar value Expr\n\tswitch {\n\tcase p.matchTokenKind(TokenKindString):\n\t\tliteral, err := p.parseLiteral(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue = literal\n\tcase p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat):\n\t\tliteral, err := p.parseLiteral(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue = literal\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue = ident\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected string, number or identifier in named collection parameter, got %s\", p.lastTokenKind())\n\t}\n\n\tparam := &NamedCollectionParam{\n\t\tParamPos: pos,\n\t\tName:     name,\n\t\tValue:    value,\n\t}\n\n\t// Parse optional [NOT] OVERRIDABLE clause\n\tif p.tryConsumeKeywords(KeywordNot) {\n\t\tparam.NotOverridable = true\n\t\tif err := p.expectKeyword(KeywordOverridable); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if p.tryConsumeKeywords(KeywordOverridable) {\n\t\tparam.Overridable = true\n\t}\n\n\treturn param, nil\n}\n\nfunc (p *Parser) parseCreateTable(pos Pos, orReplace bool) (*CreateTable, error) {\n\tcreateTable := &CreateTable{CreatePos: pos, OrReplace: orReplace}\n\tcreateTable.HasTemporary = p.tryConsumeKeywords(KeywordTemporary)\n\n\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse IF NOT EXISTS clause if exists\n\tvar err error\n\tcreateTable.IfNotExists, err = p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateTable.Name = tableIdentifier\n\n\t// try parse UUID clause if exists\n\tuuid, err := p.tryParseUUID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateTable.UUID = uuid\n\t// parse ON CLUSTER clause if exists\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateTable.OnCluster = onCluster\n\n\ttableSchema, err := p.parseTableSchemaClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateTable.TableSchema = tableSchema\n\n\tengineExpr, err := p.tryParseEngineExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif engineExpr != nil {\n\t\tcreateTable.Engine = engineExpr\n\t\tcreateTable.StatementEnd = engineExpr.End()\n\t}\n\n\tif p.tryConsumeKeywords(KeywordAs) {\n\t\t// After AS, we can have: SELECT/WITH (with or without parens), or table_function(...)\n\t\t// Check if it's a SELECT/WITH query (explicitly check keywords/paren before ident)\n\t\tif p.matchKeyword(KeywordSelect) || p.matchKeyword(KeywordWith) || p.matchTokenKind(TokenKindLParen) {\n\t\t\t// It's a SELECT or WITH query (with or without parentheses)\n\t\t\tsubQuery, err := p.parseSubQuery(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcreateTable.SubQuery = subQuery\n\t\t\tcreateTable.StatementEnd = subQuery.End()\n\t\t} else if p.matchTokenKind(TokenKindIdent) {\n\t\t\t// It's a table function: remote(...), remoteSecure(...), etc.\n\t\t\tident, err := p.parseIdent()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif p.matchTokenKind(TokenKindLParen) {\n\t\t\t\targsExpr, err := p.parseTableArgList(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\ttableFunc := &TableFunctionExpr{\n\t\t\t\t\tName: ident,\n\t\t\t\t\tArgs: argsExpr,\n\t\t\t\t}\n\t\t\t\tcreateTable.TableFunction = tableFunc\n\t\t\t\tcreateTable.StatementEnd = tableFunc.End()\n\t\t\t} else {\n\t\t\t\treturn nil, fmt.Errorf(\"expected ( after identifier in AS clause, got %q\", p.lastTokenKind())\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"expected SELECT, WITH or identifier after AS, got %q\", p.lastTokenKind())\n\t\t}\n\t}\n\n\tcomment, err := p.tryParseComment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateTable.Comment = comment\n\treturn createTable, nil\n}\n\nfunc (p *Parser) parseIdentOrFunction(_ Pos) (Expr, error) {\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch {\n\tcase p.matchTokenKind(TokenKindLBracket):\n\t\tparams, err := p.parseArrayParams(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &ObjectParams{\n\t\t\tObject: ident,\n\t\t\tParams: params,\n\t\t}, nil\n\tcase p.matchTokenKind(TokenKindLParen):\n\t\tparams, err := p.parseFunctionParams(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfuncExpr := &FunctionExpr{\n\t\t\tName:   ident,\n\t\t\tParams: params,\n\t\t}\n\n\t\toverPos := p.Pos()\n\t\tif p.tryConsumeKeywords(KeywordOver) {\n\t\t\tvar overExpr Expr\n\t\t\tswitch {\n\t\t\tcase p.matchTokenKind(TokenKindIdent):\n\t\t\t\toverExpr, err = p.parseIdent()\n\t\t\tcase p.matchTokenKind(TokenKindLParen):\n\t\t\t\toverExpr, err = p.parseWindowCondition(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"expected window name or (, but got %q\", p.lastTokenKind())\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &WindowFunctionExpr{\n\t\t\t\tFunction: funcExpr,\n\t\t\t\tOverPos:  overPos,\n\t\t\t\tOverExpr: overExpr,\n\t\t\t}, nil\n\t\t}\n\t\treturn funcExpr, nil\n\tcase p.tryConsumeTokenKind(TokenKindDot) != nil:\n\t\tswitch {\n\t\tcase p.matchTokenKind(TokenKindIdent):\n\t\t\tfields := []*Ident{ident}\n\t\t\tfor {\n\t\t\t\tchild, err := p.parseIdent()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tfields = append(fields, child)\n\t\t\t\tif p.tryConsumeTokenKind(TokenKindDot) == nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn &Path{Fields: fields}, nil\n\t\tcase p.matchTokenKind(\"*\"):\n\t\t\tnextIdent, err := p.parseColumnStar(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &NestedIdentifier{\n\t\t\t\tIdent:    ident,\n\t\t\t\tDotIdent: nextIdent,\n\t\t\t}, nil\n\t\tcase p.matchTokenKind(TokenKindInt):\n\t\t\ti, err := p.parseNumber(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &IndexOperation{\n\t\t\t\tObject:    ident,\n\t\t\t\tOperation: TokenKindDot,\n\t\t\t\tIndex:     i,\n\t\t\t}, nil\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"expected IDENT, NUMBER or *, but got %q\", p.lastTokenKind())\n\t\t}\n\t}\n\treturn ident, nil\n}\n\nfunc (p *Parser) parseTableIdentifier(_ Pos) (*TableIdentifier, error) {\n\tident, err := p.parseIdentOrString()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdotIdent, err := p.tryParseDotIdentOrString(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif dotIdent != nil {\n\t\treturn &TableIdentifier{\n\t\t\tDatabase: ident,\n\t\t\tTable:    dotIdent,\n\t\t}, nil\n\t}\n\treturn &TableIdentifier{\n\t\tTable: ident,\n\t}, nil\n}\n\nfunc (p *Parser) parseTableSchemaClause(pos Pos) (*TableSchemaClause, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindLParen):\n\t\t// parse column definitions\n\t\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcolumns, err := p.parseTableColumns()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\trightParenPos := p.Pos()\n\t\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &TableSchemaClause{\n\t\t\tSchemaPos: pos,\n\t\t\tSchemaEnd: rightParenPos,\n\t\t\tColumns:   columns,\n\t\t}, nil\n\tcase p.matchKeyword(KeywordAs) && !p.peekKeyword(KeywordSelect) && !p.peekKeyword(KeywordWith) && !p.peekTokenKind(TokenKindLParen):\n\t\t// Handle AS only if followed by identifier (not SELECT/WITH/LPAREN)\n\t\t// This handles: AS ident, AS ident.ident, AS ident(...)\n\t\t// CREATE TABLE will handle: AS SELECT, AS WITH, AS (SELECT ...)\n\t\tp.tryConsumeKeywords(KeywordAs)\n\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch {\n\t\tcase p.matchTokenKind(TokenKindDot):\n\t\t\t// it's a database.table\n\t\t\tdotIdent, err := p.tryParseDotIdent(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &TableSchemaClause{\n\t\t\t\tSchemaPos: pos,\n\t\t\t\tSchemaEnd: dotIdent.End(),\n\t\t\t\tAliasTable: &TableIdentifier{\n\t\t\t\t\tDatabase: ident,\n\t\t\t\t\tTable:    dotIdent,\n\t\t\t\t},\n\t\t\t}, nil\n\t\tcase p.matchTokenKind(TokenKindLParen):\n\t\t\t// it's a table function\n\t\t\targsExpr, err := p.parseTableArgList(pos)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &TableSchemaClause{\n\t\t\t\tSchemaPos: pos,\n\t\t\t\tSchemaEnd: p.End(),\n\t\t\t\tTableFunction: &TableFunctionExpr{\n\t\t\t\t\tName: ident,\n\t\t\t\t\tArgs: argsExpr,\n\t\t\t\t},\n\t\t\t}, nil\n\t\tdefault:\n\t\t\treturn &TableSchemaClause{\n\t\t\t\tSchemaPos: pos,\n\t\t\t\tSchemaEnd: p.End(),\n\t\t\t\tAliasTable: &TableIdentifier{\n\t\t\t\t\tTable: ident,\n\t\t\t\t},\n\t\t\t}, nil\n\t\t}\n\t}\n\t// no schema is ok for MATERIALIZED VIEW\n\treturn nil, nil\n}\n\nfunc (p *Parser) parseTableColumns() ([]Expr, error) {\n\tcolumns := make([]Expr, 0)\n\tfor !p.lexer.isEOF() {\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordIndex):\n\t\t\tindexPos := p.Pos()\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tindex, err := p.parseTableIndex(indexPos)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcolumns = append(columns, index)\n\t\tcase p.matchKeyword(KeywordConstraint):\n\t\t\tconstraintPos := p.Pos()\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tident, err := p.parseIdent()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif err := p.expectKeyword(KeywordCheck); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\texpr, err := p.parseExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcolumns = append(columns, &ConstraintClause{\n\t\t\t\tConstraintPos: constraintPos,\n\t\t\t\tConstraint:    ident,\n\t\t\t\tExpr:          expr,\n\t\t\t})\n\t\tcase p.matchKeyword(KeywordProjection):\n\t\t\tprojection, err := p.parseTableProjection(p.Pos(), true)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcolumns = append(columns, projection)\n\t\tdefault:\n\t\t\tcolumn, err := p.tryParseTableColumnExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif column == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcolumns = append(columns, column)\n\t\t}\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\t// end of column definitions\n\treturn columns, nil\n}\n\nfunc (p *Parser) tryParseTableColumnExpr(pos Pos) (*ColumnDef, error) {\n\tif !p.matchTokenKind(TokenKindIdent) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseTableColumnExpr(pos)\n}\n\nfunc (p *Parser) parseTableColumnExpr(pos Pos) (*ColumnDef, error) {\n\t// Not a column definition, just return\n\tcolumn := &ColumnDef{NamePos: pos}\n\t// parse column name\n\tname, err := p.ParseNestedIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcolumn.Name = name\n\tcolumnEnd := name.End()\n\n\tif p.matchTokenKind(TokenKindIdent) && !p.matchKeyword(KeywordRemove) {\n\t\tcolumnType, err := p.parseColumnType(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcolumn.Type = columnType\n\t\tcolumnEnd = columnType.End()\n\t}\n\n\tnullable := p.tryParseNull(p.Pos())\n\tif nullable != nil {\n\t\tcolumnEnd = nullable.End()\n\t}\n\tnotNull, err := p.tryParseNotNull(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif notNull != nil {\n\t\tcolumnEnd = notNull.End()\n\t}\n\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordDefault):\n\t\tcolumn.DefaultExpr, err = p.parseExpr(p.Pos())\n\t\tcolumnEnd = column.DefaultExpr.End()\n\tcase p.tryConsumeKeywords(KeywordMaterialized):\n\t\tcolumn.MaterializedExpr, err = p.parseExpr(p.Pos())\n\t\tcolumnEnd = column.MaterializedExpr.End()\n\tcase p.tryConsumeKeywords(KeywordAlias):\n\t\tcolumn.AliasExpr, err = p.parseExpr(p.Pos())\n\t\tcolumnEnd = column.AliasExpr.End()\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcomment, err := p.tryParseColumnComment(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif comment != nil {\n\t\tcolumnEnd = comment.End()\n\t}\n\n\tcodec, err := p.tryParseCompressionCodecs(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif codec != nil {\n\t\tcolumnEnd = codec.End()\n\t}\n\tttl, err := p.tryParseTTLClause(p.Pos(), false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif ttl != nil {\n\t\tcolumnEnd = ttl.End()\n\t}\n\tcolumn.TTL = ttl\n\n\tcolumn.ColumnEnd = columnEnd\n\tcolumn.Comment = comment\n\tcolumn.Codec = codec\n\tcolumn.Nullable = nullable\n\tcolumn.NotNull = notNull\n\treturn column, nil\n}\n\nfunc (p *Parser) parseTableArgExpr(pos Pos) (Expr, error) {\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch {\n\t\t// nest identifier\n\t\tcase p.matchTokenKind(TokenKindDot):\n\t\t\tdotIdent, err := p.tryParseDotIdent(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &NestedIdentifier{\n\t\t\t\tIdent:    ident,\n\t\t\t\tDotIdent: dotIdent,\n\t\t\t}, nil\n\t\tcase p.matchTokenKind(TokenKindLParen):\n\t\t\targsExpr, err := p.parseTableArgList(pos)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &TableFunctionExpr{\n\t\t\t\tName: ident,\n\t\t\t\tArgs: argsExpr,\n\t\t\t}, nil\n\t\tdefault:\n\t\t\treturn ident, nil\n\t\t}\n\tcase p.matchTokenKind(TokenKindLParen):\n\t\treturn p.parseSubQuery(p.Pos())\n\tcase p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindString), p.matchKeyword(KeywordNull):\n\t\treturn p.parseLiteral(p.Pos())\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token: %q, expected <Name>, <literal>\", p.last().String)\n\t}\n}\n\nfunc (p *Parser) parseTableArgList(pos Pos) (*TableArgListExpr, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\targs := make([]Expr, 0)\n\tfor !p.lexer.isEOF() {\n\t\t// Check if this is a named parameter (identifier followed by =)\n\t\tvar arg Expr\n\t\tvar err error\n\n\t\t// Try to detect named parameter pattern: last token is identifier, next token is =\n\t\tisNamedParam := false\n\t\tlastKind := p.lastTokenKind()\n\t\tif lastKind == TokenKindIdent || lastKind == TokenKindKeyword {\n\t\t\t// Last token is an identifier, peek at the next token\n\t\t\tnextToken, peekErr := p.lexer.peekToken()\n\n\t\t\tif peekErr == nil && nextToken != nil && nextToken.Kind == TokenKindSingleEQ {\n\t\t\t\tisNamedParam = true\n\t\t\t}\n\t\t}\n\n\t\tif isNamedParam {\n\t\t\t// Parse as named parameter - the identifier is already the last token\n\t\t\t// We need to get it, consume the =, and parse the value\n\t\t\tname := &Ident{\n\t\t\t\tNamePos: p.last().Pos,\n\t\t\t\tNameEnd: p.last().End,\n\t\t\t\tName:    p.last().String,\n\t\t\t}\n\t\t\t// Consume the = token\n\t\t\tif err := p.lexer.consumeToken(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// Parse the value\n\t\t\tvalue, err := p.parseTableArgExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\targ = &NamedParameterExpr{\n\t\t\t\tNamePos: name.NamePos,\n\t\t\t\tName:    name,\n\t\t\t\tValue:   value,\n\t\t\t}\n\t\t} else {\n\t\t\t// Parse as regular table arg expression\n\t\t\targ, err = p.parseTableArgExpr(p.Pos())\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targs = append(args, arg)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &TableArgListExpr{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tArgs:          args,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseClusterClause(pos Pos) (*ClusterClause, error) {\n\tif !p.tryConsumeKeywords(KeywordOn) {\n\t\treturn nil, nil // nolint\n\t}\n\tif err := p.expectKeyword(KeywordCluster); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar expr Expr\n\tvar err error\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\texpr, err = p.parseIdent()\n\tcase p.matchTokenKind(TokenKindString):\n\t\texpr, err = p.parseString(p.Pos())\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token: %q, expected <IDENT> or <STRING>\", p.last().String)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ClusterClause{\n\t\tOnPos: pos,\n\t\tExpr:  expr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParsePartitionByClause(pos Pos) (*PartitionByClause, error) {\n\tif !p.tryConsumeKeywords(KeywordPartition) {\n\t\treturn nil, nil // nolint\n\t}\n\n\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse partition key list\n\tcolumnExpr, err := p.parseColumnExprListWithLParen(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &PartitionByClause{\n\t\tPartitionPos: pos,\n\t\tExpr:         columnExpr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParsePrimaryKeyClause(pos Pos) (*PrimaryKeyClause, error) {\n\tif !p.tryConsumeKeywords(KeywordPrimary) {\n\t\treturn nil, nil // nolint\n\t}\n\n\tif err := p.expectKeyword(KeywordKey); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse partition key list\n\tcolumnExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &PrimaryKeyClause{\n\t\tPrimaryPos: pos,\n\t\tExpr:       columnExpr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseOrderByClause(pos Pos) (*OrderByClause, error) {\n\tif !p.tryConsumeKeywords(KeywordOrder) {\n\t\treturn nil, nil // nolint\n\t}\n\n\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p.parseOrderByClause(pos)\n}\n\nfunc (p *Parser) parseOrderByClause(pos Pos) (*OrderByClause, error) {\n\torderByListExpr := &OrderByClause{OrderPos: pos, ListEnd: pos}\n\titems := make([]Expr, 0)\n\tfor {\n\t\texpr, err := p.parseOrderExpr(pos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif expr == nil {\n\t\t\tbreak\n\t\t}\n\t\titems = append(items, expr)\n\n\t\tif p.lexer.isEOF() || p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tif len(items) > 0 {\n\t\torderByListExpr.ListEnd = items[len(items)-1].End()\n\t}\n\torderByListExpr.Items = items\n\n\t// Parse optional INTERPOLATE clause\n\tif p.matchKeyword(KeywordInterpolate) {\n\t\tinterpolatePos := p.Pos()\n\t\t_ = p.lexer.consumeToken()\n\t\tinterpolate, err := p.parseInterpolateClause(interpolatePos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\torderByListExpr.Interpolate = interpolate\n\t\torderByListExpr.ListEnd = interpolate.End()\n\t}\n\n\treturn orderByListExpr, nil\n}\n\nfunc (p *Parser) parseOrderExpr(pos Pos) (*OrderExpr, error) {\n\t// parse column expr\n\tcolumnExpr, err := p.parseExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar alias *Ident\n\tif p.matchKeyword(KeywordAs) {\n\t\t// It should be a subquery instead of an order by alias if the `AS` is followed by `SELECT` keyword.\n\t\tif nextToken, err := p.lexer.peekToken(); err == nil && nextToken.ToString() == KeywordSelect {\n\t\t\treturn &OrderExpr{\n\t\t\t\tOrderPos: pos,\n\t\t\t\tExpr:     columnExpr,\n\t\t\t}, nil\n\t\t}\n\t\t// consume the `AS` keyword\n\t\t_ = p.lexer.consumeToken()\n\t\talias, err = p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if p.matchKeyword(KeywordTtl) {\n\t\treturn &OrderExpr{\n\t\t\tOrderPos: pos,\n\t\t\tExpr:     columnExpr,\n\t\t}, nil\n\t}\n\n\tdirection := OrderDirectionNone\n\tswitch {\n\tcase p.matchKeyword(KeywordAsc), p.matchKeyword(KeywordAscending):\n\t\tdirection = OrderDirectionAsc\n\t\t_ = p.lexer.consumeToken()\n\tcase p.matchKeyword(KeywordDesc), p.matchKeyword(KeywordDescending):\n\t\tdirection = OrderDirectionDesc\n\t\t_ = p.lexer.consumeToken()\n\t}\n\n\t// Parse optional WITH FILL clause\n\tvar fill *Fill\n\tif p.tryConsumeKeywords(KeywordWith, KeywordFill) {\n\t\tfillPos := p.Pos()\n\t\tfill, err = p.parseFillClause(fillPos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &OrderExpr{\n\t\tOrderPos:  pos,\n\t\tAlias:     alias,\n\t\tExpr:      columnExpr,\n\t\tDirection: direction,\n\t\tFill:      fill,\n\t}, nil\n}\n\nfunc (p *Parser) parseFillClause(fillPos Pos) (*Fill, error) {\n\tfill := &Fill{FillPos: fillPos}\n\n\t// Parse optional FROM clause\n\tif p.tryConsumeKeywords(KeywordFrom) {\n\t\tfromExpr, err := p.parseExpr(fillPos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfill.From = fromExpr\n\t}\n\n\t// Parse optional TO clause\n\tif p.tryConsumeKeywords(KeywordTo) {\n\t\ttoExpr, err := p.parseExpr(fillPos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfill.To = toExpr\n\t}\n\n\t// Parse optional STEP clause\n\tif p.tryConsumeKeywords(KeywordStep) {\n\t\tstepExpr, err := p.parseExpr(fillPos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfill.Step = stepExpr\n\t}\n\n\t// Parse optional STALENESS clause\n\tif p.tryConsumeKeywords(KeywordStaleness) {\n\t\tstalenessExpr, err := p.parseExpr(fillPos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfill.Staleness = stalenessExpr\n\t}\n\n\treturn fill, nil\n}\n\nfunc (p *Parser) parseInterpolateClause(interpolatePos Pos) (*InterpolateClause, error) {\n\tinterpolate := &InterpolateClause{\n\t\tInterpolatePos: interpolatePos,\n\t\tListEnd:        interpolatePos + Pos(len(\"INTERPOLATE\")),\n\t}\n\n\tif p.tryConsumeTokenKind(TokenKindLParen) == nil {\n\t\t// INTERPOLATE without columns is valid\n\t\treturn interpolate, nil\n\t}\n\n\titems := make([]*InterpolateItem, 0)\n\tfor {\n\t\tcolumn, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\titem := &InterpolateItem{Column: column}\n\n\t\tif p.tryConsumeKeywords(KeywordAs) {\n\t\t\texpr, err := p.parseExpr(interpolatePos)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\titem.Expr = expr\n\t\t}\n\n\t\titems = append(items, item)\n\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trparen := p.tryConsumeTokenKind(TokenKindRParen)\n\tif rparen == nil {\n\t\treturn nil, fmt.Errorf(\"expected ')' after INTERPOLATE column list\")\n\t}\n\n\tinterpolate.Items = items\n\tinterpolate.ListEnd = rparen.End\n\n\treturn interpolate, nil\n}\n\nfunc (p *Parser) tryParseTTLClause(pos Pos, allowMultiValues bool) (*TTLClause, error) {\n\tif !p.tryConsumeKeywords(KeywordTtl) {\n\t\treturn nil, nil // nolint\n\t}\n\tttlExprList := &TTLClause{TTLPos: pos, ListEnd: pos}\n\t// accept the TTL keyword\n\titems, err := p.parseTTLClause(pos, allowMultiValues)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(items) > 0 {\n\t\tttlExprList.ListEnd = items[len(items)-1].End()\n\t}\n\tttlExprList.Items = items\n\treturn ttlExprList, nil\n}\n\n// parseTTLClause parses the TTL clause.\n// allowMultiValues is used to determine whether to allow multiple TTL values.\nfunc (p *Parser) parseTTLClause(pos Pos, allowMultiValues bool) ([]*TTLExpr, error) {\n\titems := make([]*TTLExpr, 0)\n\texpr, err := p.parseTTLExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\titems = append(items, expr)\n\tfor allowMultiValues && !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\texpr, err = p.parseTTLExpr(pos)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, expr)\n\t}\n\treturn items, nil\n}\n\nfunc (p *Parser) tryParseTTLPolicy(pos Pos) (*TTLPolicy, error) {\n\tvar rule *TTLPolicyRule\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordTo):\n\t\tif p.tryConsumeKeywords(KeywordDisk) {\n\t\t\tvalue, err := p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\trule = &TTLPolicyRule{RulePos: pos, ToDisk: value}\n\t\t} else if p.tryConsumeKeywords(KeywordVolume) {\n\t\t\tvalue, err := p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\trule = &TTLPolicyRule{RulePos: pos, ToVolume: value}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"unexpected token: %q, expected DISK or VOLUME\", p.lastTokenKind())\n\t\t}\n\tcase p.matchKeyword(KeywordDelete), p.matchKeyword(KeywordRecompress):\n\t\ttoken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\taction := &TTLPolicyRuleAction{\n\t\t\tActionPos: token.Pos,\n\t\t\tActionEnd: token.End,\n\t\t\tAction:    token.ToString(),\n\t\t}\n\t\tcodec, err := p.tryParseCompressionCodecs(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\taction.Codec = codec\n\t\trule = &TTLPolicyRule{RulePos: pos, Action: action}\n\tdefault:\n\t\treturn nil, nil // nolint\n\t}\n\tpolicy := &TTLPolicy{Item: rule}\n\n\twhere, err := p.tryParseWhereClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpolicy.Where = where\n\n\tgroupBy, err := p.tryParseGroupByClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpolicy.GroupBy = groupBy\n\treturn policy, nil\n}\n\nfunc (p *Parser) parseTTLExpr(pos Pos) (*TTLExpr, error) {\n\tcolumnExpr, err := p.parseExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpolicy, err := p.tryParseTTLPolicy(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &TTLExpr{\n\t\tTTLPos: pos,\n\t\tExpr:   columnExpr,\n\t\tPolicy: policy,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseSampleByClause(pos Pos) (*SampleByClause, error) {\n\tif !p.tryConsumeKeywords(KeywordSample) {\n\t\treturn nil, nil // nolint\n\t}\n\n\tif err := p.expectKeyword(KeywordBy); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// parse sample by expr\n\tcolumnExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SampleByClause{\n\t\tSamplePos: pos,\n\t\tExpr:      columnExpr,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseSettingsClause(pos Pos) (*SettingsClause, error) {\n\tif !p.tryConsumeKeywords(KeywordSettings) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseSettingsClause(pos)\n}\n\nfunc (p *Parser) parseSettingsClause(pos Pos) (*SettingsClause, error) {\n\tsettings := &SettingsClause{SettingsPos: pos, ListEnd: pos}\n\titems, err := p.parseSettingsList(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(items) == 0 {\n\t\treturn nil, fmt.Errorf(\"settings list is empty\")\n\t}\n\tsettings.ListEnd = items[len(items)-1].End()\n\tsettings.Items = items\n\treturn settings, nil\n}\n\nfunc (p *Parser) parseSettingsList(pos Pos) ([]*SettingExpr, error) {\n\titems := make([]*SettingExpr, 0)\n\texpr, err := p.parseSettingsExpr(pos)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\titems = append(items, expr)\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\texpr, err = p.parseSettingsExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, expr)\n\t}\n\treturn items, nil\n}\n\nfunc (p *Parser) parseSettingsExpr(pos Pos) (*SettingExpr, error) {\n\tident, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar expr Expr\n\tswitch {\n\tcase p.matchTokenKind(TokenKindInt):\n\t\tnumber, err := p.parseNumber(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texpr = number\n\tcase p.matchTokenKind(TokenKindString):\n\t\tstr, err := p.parseString(p.Pos())\n\t\texpr = str\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase p.matchTokenKind(TokenKindLBrace):\n\t\tm, err := p.parseMapLiteral(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texpr = m\n\tcase p.matchKeyword(KeywordTrue), p.matchKeyword(KeywordFalse):\n\t\t// Handle TRUE/FALSE keywords as boolean literals\n\t\tlastToken := p.last()\n\t\t_ = p.lexer.consumeToken()\n\t\texpr = &BoolLiteral{\n\t\t\tLiteralPos: lastToken.Pos,\n\t\t\tLiteralEnd: lastToken.End,\n\t\t\tLiteral:    lastToken.String,\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token: %q, expected <number>, <bool> or <string>\", p.last().String)\n\t}\n\n\treturn &SettingExpr{\n\t\tSettingsPos: pos,\n\t\tName:        ident,\n\t\tExpr:        expr,\n\t}, nil\n}\n\nfunc (p *Parser) parseDestinationClause(pos Pos) (*DestinationClause, error) {\n\tif err := p.expectKeyword(KeywordTo); err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DestinationClause{\n\t\tToPos:           pos,\n\t\tTableIdentifier: tableIdentifier,\n\t}, nil\n}\n\nfunc (p *Parser) tryParseEngineExpr(pos Pos) (*EngineExpr, error) {\n\tif !p.matchKeyword(KeywordEngine) {\n\t\treturn nil, nil // nolint\n\t}\n\treturn p.parseEngineExpr(pos)\n}\n\nfunc (p *Parser) parseEngineExpr(pos Pos) (*EngineExpr, error) {\n\tif err := p.expectKeyword(KeywordEngine); err != nil {\n\t\treturn nil, err\n\t}\n\t_ = p.tryConsumeTokenKind(TokenKindSingleEQ)\n\n\tengineExpr := &EngineExpr{EnginePos: pos}\n\tvar engineEnd Pos\n\tswitch {\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tengineExpr.Name = ident.Name\n\t\tengineEnd = ident.End()\n\t\tif p.matchTokenKind(TokenKindLParen) {\n\t\t\tparams, err := p.parseFunctionParams(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.Params = params\n\t\t\tengineExpr.EngineEnd = params.End()\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token: %s\", p.lastTokenKind())\n\t}\n\n\tfor !p.lexer.isEOF() {\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordOrder):\n\t\t\torderBy, err := p.tryParseOrderByClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.OrderBy = orderBy\n\t\t\tengineEnd = orderBy.End()\n\t\tcase p.matchKeyword(KeywordPartition):\n\t\t\tpartitionBy, err := p.tryParsePartitionByClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.PartitionBy = partitionBy\n\t\t\tengineEnd = partitionBy.End()\n\t\tcase p.matchKeyword(KeywordPrimary):\n\t\t\tprimaryKey, err := p.tryParsePrimaryKeyClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.PrimaryKey = primaryKey\n\t\t\tengineEnd = primaryKey.End()\n\t\tcase p.matchKeyword(KeywordSample):\n\t\t\tsampleBy, err := p.tryParseSampleByClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.SampleBy = sampleBy\n\t\t\tengineEnd = sampleBy.End()\n\t\tcase p.matchKeyword(KeywordTtl):\n\t\t\tttl, err := p.tryParseTTLClause(p.Pos(), true)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.TTL = ttl\n\t\t\tengineEnd = ttl.End()\n\t\tcase p.matchKeyword(KeywordSettings):\n\t\t\tsettingsClause, err := p.tryParseSettingsClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengineExpr.Settings = settingsClause\n\t\t\tengineEnd = settingsClause.End()\n\t\tdefault:\n\t\t\tengineExpr.EngineEnd = engineEnd\n\t\t\treturn engineExpr, nil\n\t\t}\n\t}\n\tengineExpr.EngineEnd = engineEnd\n\treturn engineExpr, nil\n}\n\nfunc (p *Parser) parseStmt(pos Pos) (Expr, error) {\n\tvar err error\n\tvar expr Expr\n\tswitch {\n\tcase p.matchKeyword(KeywordCreate),\n\t\tp.matchKeyword(KeywordAttach),\n\t\tp.matchKeyword(KeywordAlter),\n\t\tp.matchKeyword(KeywordDrop),\n\t\tp.matchKeyword(KeywordDetach),\n\t\tp.matchKeyword(KeywordTruncate),\n\t\tp.matchKeyword(KeywordRename):\n\t\texpr, err = p.parseDDL(pos)\n\tcase p.matchKeyword(KeywordSelect), p.matchKeyword(KeywordWith):\n\t\texpr, err = p.parseSelectQuery(pos)\n\tcase p.matchKeyword(KeywordDelete):\n\t\texpr, err = p.parseDeleteClause(pos)\n\tcase p.matchKeyword(KeywordInsert):\n\t\texpr, err = p.parseInsertStmt(p.Pos())\n\tcase p.matchKeyword(KeywordUse):\n\t\texpr, err = p.parseUseStmt(pos)\n\tcase p.matchKeyword(KeywordSet):\n\t\texpr, err = p.parseSetStmt(pos)\n\tcase p.matchKeyword(KeywordSettings):\n\t\texpr, err = p.parseSettingsStmt(pos)\n\tcase p.matchKeyword(KeywordSystem):\n\t\texpr, err = p.parseSystemStmt(pos)\n\tcase p.matchKeyword(KeywordOptimize):\n\t\texpr, err = p.parseOptimizeStmt(pos)\n\tcase p.matchKeyword(KeywordCheck):\n\t\texpr, err = p.parseCheckStmt(pos)\n\tcase p.matchKeyword(KeywordExplain):\n\t\texpr, err = p.parseExplainStmt(pos)\n\tcase p.matchKeyword(KeywordGrant):\n\t\texpr, err = p.parseGrantPrivilegeStmt(pos)\n\tcase p.matchKeyword(KeywordShow):\n\t\texpr, err = p.parseShowStmt(pos)\n\tcase p.matchKeyword(KeywordDesc), p.matchKeyword(KeywordDescribe):\n\t\texpr, err = p.parseDescribeStmt(pos)\n\tdefault:\n\t\tif p.last() == nil {\n\t\t\treturn nil, errors.New(\"unexpected end of input\")\n\t\t}\n\t\treturn nil, fmt.Errorf(\"unexpected token: %q\", p.last().String)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = p.tryParseFormat(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Statement can be terminated by ';' or EOF\n\tif p.last() != nil && !p.matchTokenKind(\";\") {\n\t\treturn nil, fmt.Errorf(\"<EOF> or ';' was expected, but got: %q\", p.last().String)\n\t}\n\treturn expr, nil\n}\n\nfunc (p *Parser) ParseStmts() ([]Expr, error) {\n\tvar stmts []Expr\n\tfor {\n\t\tif err := p.lexer.consumeToken(); err != nil {\n\t\t\treturn nil, p.wrapError(err)\n\t\t}\n\t\tif p.lexer.isEOF() {\n\t\t\tbreak\n\t\t}\n\t\tif p.matchTokenKind(\";\") {\n\t\t\tcontinue\n\t\t}\n\t\tstmt, err := p.parseStmt(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, p.wrapError(err)\n\t\t}\n\t\tstmts = append(stmts, stmt)\n\t}\n\treturn stmts, nil\n}\n\nfunc (p *Parser) parseUseStmt(pos Pos) (*UseStmt, error) {\n\tif err := p.expectKeyword(KeywordUse); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdatabase, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &UseStmt{\n\t\tUsePos:       pos,\n\t\tDatabase:     database,\n\t\tStatementEnd: database.End(),\n\t}, nil\n}\n\nfunc (p *Parser) parseShowStmt(pos Pos) (*ShowStmt, error) {\n\tif err := p.expectKeyword(KeywordShow); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar showType string\n\tvar target *TableIdentifier\n\n\t// Parse the type of SHOW statement\n\tswitch {\n\tcase p.matchKeyword(KeywordCreate):\n\t\t// SHOW CREATE TABLE table_name\n\t\tshowType = \"CREATE\"\n\t\t_ = p.lexer.consumeToken()\n\n\t\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tshowType += \" TABLE\"\n\n\t\ttableIdent, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttarget = tableIdent\n\n\tcase p.matchKeyword(KeywordDatabases):\n\t\t// SHOW DATABASES [optional clauses]\n\t\tshowType = \"DATABASES\"\n\t\t_ = p.lexer.consumeToken()\n\n\tcase p.matchKeyword(KeywordTables):\n\t\t// SHOW TABLES\n\t\tshowType = \"TABLES\"\n\t\t_ = p.lexer.consumeToken()\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected CREATE, DATABASES, or TABLES after SHOW, got %q\", p.last().String)\n\t}\n\n\tstmt := &ShowStmt{\n\t\tShowPos:  pos,\n\t\tShowType: showType,\n\t\tTarget:   target,\n\t}\n\n\t// Parse optional clauses for SHOW DATABASES\n\tif showType == \"DATABASES\" {\n\t\t// Parse [[NOT] LIKE | ILIKE '<pattern>']\n\t\tif p.matchKeyword(KeywordNot) {\n\t\t\tstmt.NotLike = true\n\t\t\t_ = p.lexer.consumeToken()\n\t\t}\n\n\t\tif p.matchKeyword(KeywordLike) || p.matchKeyword(KeywordIlike) {\n\t\t\tif p.matchKeyword(KeywordLike) {\n\t\t\t\tstmt.LikeType = \"LIKE\"\n\t\t\t} else {\n\t\t\t\tstmt.LikeType = \"ILIKE\"\n\t\t\t}\n\t\t\t_ = p.lexer.consumeToken()\n\n\t\t\t// Parse pattern expression\n\t\t\tpattern, err := p.parseExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tstmt.LikePattern = pattern\n\t\t}\n\n\t\t// Parse [LIMIT <N>]\n\t\tif p.matchKeyword(KeywordLimit) {\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tlimit, err := p.parseExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tstmt.Limit = limit\n\t\t}\n\n\t\t// Parse [INTO OUTFILE filename]\n\t\tif p.matchKeyword(KeywordInto) {\n\t\t\t_ = p.lexer.consumeToken()\n\t\t\tif err := p.expectKeyword(KeywordOutfile); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Parse filename as a string literal\n\t\t\toutFile, err := p.parseString(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tstmt.OutFile = outFile\n\t\t}\n\n\t\t// Parse [FORMAT format]\n\t\tif p.matchKeyword(KeywordFormat) {\n\t\t\t_ = p.lexer.consumeToken()\n\n\t\t\t// Format can be an identifier or a string\n\t\t\tif p.matchTokenKind(TokenKindString) {\n\t\t\t\tformat, err := p.parseString(p.Pos())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tstmt.Format = format\n\t\t\t} else if p.matchTokenKind(TokenKindIdent) {\n\t\t\t\t// Handle format as identifier (like JSON, CSV, etc.)\n\t\t\t\ttoken := p.last()\n\t\t\t\t_ = p.lexer.consumeToken()\n\t\t\t\tstmt.Format = &StringLiteral{\n\t\t\t\t\tLiteralPos: token.Pos,\n\t\t\t\t\tLiteralEnd: token.End,\n\t\t\t\t\tLiteral:    token.String,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn nil, fmt.Errorf(\"expected format specification after FORMAT, got %q\", p.last().String)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set statement end position\n\tstmt.StatementEnd = p.End()\n\n\treturn stmt, nil\n}\n\nfunc (p *Parser) parseDescribeStmt(pos Pos) (*DescribeStmt, error) {\n\t// DESC and DESCRIBE are both supported\n\tif !p.matchKeyword(KeywordDesc) && !p.matchKeyword(KeywordDescribe) {\n\t\treturn nil, fmt.Errorf(\"expected DESC or DESCRIBE\")\n\t}\n\t_ = p.lexer.consumeToken()\n\n\t// TABLE keyword is optional after DESC/DESCRIBE\n\tvar describeType string\n\tif p.matchKeyword(KeywordTable) {\n\t\t_ = p.lexer.consumeToken()\n\t\tdescribeType = \"TABLE\"\n\t}\n\n\ttableIdent, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DescribeStmt{\n\t\tDescribePos:  pos,\n\t\tStatementEnd: tableIdent.End(),\n\t\tDescribeType: describeType,\n\t\tTarget:       tableIdent,\n\t}, nil\n}\n\n// syntax: TRUNCATE TEMPORARY? TABLE (IF EXISTS)? tableIdentifier clusterClause?;\nfunc (p *Parser) parseTruncateTable(pos Pos) (*TruncateTable, error) {\n\tif err := p.expectKeyword(KeywordTruncate); err != nil {\n\t\treturn nil, err\n\t}\n\n\tisTemporary := p.tryConsumeKeywords(KeywordTemporary)\n\n\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\treturn nil, err\n\t}\n\n\tifExists, err := p.tryParseIfExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableName, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttruncateTable := &TruncateTable{\n\t\tTruncatePos:  pos,\n\t\tIsTemporary:  isTemporary,\n\t\tIfExists:     ifExists,\n\t\tName:         tableName,\n\t\tOnCluster:    onCluster,\n\t\tStatementEnd: tableName.End(),\n\t}\n\n\tif onCluster != nil {\n\t\ttruncateTable.StatementEnd = onCluster.End()\n\t}\n\n\treturn truncateTable, nil\n}\n\nfunc (p *Parser) parseDeleteClause(pos Pos) (*DeleteClause, error) {\n\tif err := p.expectKeyword(KeywordDelete); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordFrom); err != nil {\n\t\treturn nil, err\n\t}\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordWhere); err != nil {\n\t\treturn nil, err\n\t}\n\twhereExpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DeleteClause{\n\t\tDeletePos: pos,\n\t\tTable:     tableIdentifier,\n\t\tOnCluster: onCluster,\n\t\tWhereExpr: whereExpr,\n\t}, nil\n}\n\nfunc (p *Parser) parseColumnNamesExpr(pos Pos) (*ColumnNamesExpr, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar columnNames []NestedIdentifier\n\tfor !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindRParen) == nil {\n\t\tname, err := p.ParseNestedIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcolumnNames = append(columnNames, *name)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ColumnNamesExpr{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tColumnNames:   columnNames,\n\t}, nil\n}\n\nfunc (p *Parser) parseTypedPlaceholder(pos Pos) (Expr, error) {\n\tif err := p.expectTokenKind(TokenKindLBrace); err != nil {\n\t\treturn nil, err\n\t}\n\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectTokenKind(TokenKindColon); err != nil {\n\t\treturn nil, err\n\t}\n\tcolumnType, err := p.parseColumnType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindRBrace); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &TypedPlaceholder{\n\t\tLeftBracePos:  pos,\n\t\tRightBracePos: p.Pos(),\n\t\tName:          name,\n\t\tType:          columnType,\n\t}, nil\n}\n\nfunc (p *Parser) parseAssignmentValues(pos Pos) (*AssignmentValues, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar value Expr\n\tvar err error\n\tvalues := make([]Expr, 0)\n\tfor !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindRParen) == nil {\n\t\tswitch {\n\t\tcase p.matchTokenKind(TokenKindLParen):\n\t\t\tvalue, err = p.parseAssignmentValues(p.Pos())\n\t\tcase p.matchTokenKind(TokenKindLBrace):\n\t\t\t// placeholder with type, e.g. {a :Int32}, {b :DateTime(6)}\n\t\t\tvalue, err = p.parseTypedPlaceholder(p.Pos())\n\t\tdefault:\n\t\t\tvalue, err = p.parseExpr(p.Pos())\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues = append(values, value)\n\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\trightParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AssignmentValues{\n\t\tLeftParenPos:  pos,\n\t\tRightParenPos: rightParenPos,\n\t\tValues:        values,\n\t}, nil\n}\n\nfunc (p *Parser) parseInsertStmt(pos Pos) (*InsertStmt, error) {\n\tif err := p.expectKeyword(KeywordInsert); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordInto); err != nil {\n\t\treturn nil, err\n\t}\n\n\tinsertExpr := &InsertStmt{InsertPos: pos}\n\tinsertExpr.HasTableKeyword = p.tryConsumeKeywords(KeywordTable)\n\n\tvar table Expr\n\tvar err error\n\tif p.tryConsumeKeywords(KeywordFunction) {\n\t\ttable, err = p.parseFunctionExpr(p.Pos())\n\t} else {\n\t\ttable, err = p.parseTableIdentifier(p.Pos())\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinsertExpr.Table = table\n\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\t// parse column names\n\t\tinsertExpr.ColumnNames, err = p.parseColumnNamesExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tswitch {\n\tcase p.matchKeyword(KeywordFormat):\n\t\tinsertExpr.Format, err = p.parseFormat(p.Pos())\n\tcase p.matchKeyword(KeywordValues):\n\t\t// consume VALUES keyword\n\t\t_ = p.lexer.consumeToken()\n\t\tvalues := make([]*AssignmentValues, 0)\n\t\tfor !p.lexer.isEOF() {\n\t\t\tvalue, err := p.parseAssignmentValues(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tvalues = append(values, value)\n\t\t\tif p.tryConsumeTokenKind(TokenKindComma) == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tinsertExpr.Values = values\n\tcase p.matchKeyword(KeywordSelect):\n\t\tinsertExpr.SelectExpr, err = p.parseSelectQuery(p.Pos())\n\tdefault:\n\t\t// do nothing\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn insertExpr, nil\n}\n\nfunc (p *Parser) parseRenameStmt(pos Pos) (*RenameStmt, error) {\n\tif err := p.expectKeyword(KeywordRename); err != nil {\n\t\treturn nil, err\n\t}\n\n\trenameTarget := KeywordTable\n\tswitch {\n\tcase p.tryConsumeKeywords(KeywordDictionary):\n\t\trenameTarget = KeywordDictionary\n\tcase p.tryConsumeKeywords(KeywordDatabase):\n\t\trenameTarget = KeywordDatabase\n\tdefault:\n\t\tif err := p.expectKeyword(KeywordTable); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\ttargetPair, err := p.parseTargetPair(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttablePairList := []*TargetPair{targetPair}\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\ttablePair, err := p.parseTargetPair(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttablePairList = append(tablePairList, tablePair)\n\t}\n\n\trenameStmt := &RenameStmt{\n\t\tRenamePos:    pos,\n\t\tStatementEnd: tablePairList[len(tablePairList)-1].End(),\n\n\t\tRenameTarget:   renameTarget,\n\t\tTargetPairList: tablePairList,\n\t}\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif onCluster != nil {\n\t\trenameStmt.OnCluster = onCluster\n\t\trenameStmt.StatementEnd = onCluster.End()\n\t}\n\n\treturn renameStmt, nil\n}\n\nfunc (p *Parser) parseTargetPair(_ Pos) (*TargetPair, error) {\n\toldTable, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = p.expectKeyword(KeywordTo); err != nil {\n\t\treturn nil, err\n\t}\n\tnewTable, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &TargetPair{\n\t\tOld: oldTable,\n\t\tNew: newTable,\n\t}, nil\n}\n\nfunc (p *Parser) parseCreateFunction(pos Pos, orReplace bool) (*CreateFunction, error) {\n\tif err := p.expectKeyword(KeywordFunction); err != nil {\n\t\treturn nil, err\n\t}\n\tifNotExists, err := p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfunctionName, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordAs); err != nil {\n\t\treturn nil, err\n\t}\n\tparams, err := p.parseFunctionParams(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectTokenKind(TokenKindArrow); err != nil {\n\t\treturn nil, err\n\t}\n\texpr, err := p.parseExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &CreateFunction{\n\t\tCreatePos:    pos,\n\t\tOrReplace:    orReplace,\n\t\tIfNotExists:  ifNotExists,\n\t\tFunctionName: functionName,\n\t\tOnCluster:    onCluster,\n\t\tParams:       params,\n\t\tExpr:         expr,\n\t}, nil\n}\n\n// Dictionary parsing functions\n\nfunc (p *Parser) parseDictionarySchemaClause(pos Pos) (*DictionarySchemaClause, error) {\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tschema := &DictionarySchemaClause{\n\t\tSchemaPos: pos,\n\t}\n\n\t// Parse first attribute\n\tattr, err := p.parseDictionaryAttribute(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tschema.Attributes = append(schema.Attributes, attr)\n\n\t// Parse additional attributes\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\tattr, err := p.parseDictionaryAttribute(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tschema.Attributes = append(schema.Attributes, attr)\n\t}\n\n\trParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\tschema.RParenPos = rParenPos\n\n\treturn schema, nil\n}\n\nfunc (p *Parser) parseDictionaryAttribute(pos Pos) (*DictionaryAttribute, error) {\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolumnType, err := p.parseColumnType(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tattr := &DictionaryAttribute{\n\t\tNamePos: pos,\n\t\tName:    name,\n\t\tType:    columnType,\n\t}\n\n\t// Parse optional attribute properties\n\tfor {\n\t\tswitch {\n\t\tcase p.tryConsumeKeywords(KeywordDefault):\n\t\t\tif attr.Default != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate DEFAULT clause\")\n\t\t\t}\n\t\t\tliteral, err := p.parseLiteral(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tattr.Default = literal\n\t\tcase p.tryConsumeKeywords(KeywordExpression):\n\t\t\tif attr.Expression != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate EXPRESSION clause\")\n\t\t\t}\n\t\t\texpr, err := p.parseExpr(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tattr.Expression = expr\n\t\tcase p.tryConsumeKeywords(KeywordHierarchical):\n\t\t\tif attr.Hierarchical {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate HIERARCHICAL clause\")\n\t\t\t}\n\t\t\tattr.Hierarchical = true\n\t\tcase p.tryConsumeKeywords(KeywordInjective):\n\t\t\tif attr.Injective {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate INJECTIVE clause\")\n\t\t\t}\n\t\t\tattr.Injective = true\n\t\tcase p.tryConsumeKeywords(KeywordIs_object_id):\n\t\t\tif attr.IsObjectId {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate IS_OBJECT_ID clause\")\n\t\t\t}\n\t\t\tattr.IsObjectId = true\n\t\tdefault:\n\t\t\t// No more attribute properties\n\t\t\treturn attr, nil\n\t\t}\n\t}\n}\n\nfunc (p *Parser) parseDictionaryEngineClause(pos Pos) (*DictionaryEngineClause, error) {\n\tengine := &DictionaryEngineClause{\n\t\tEnginePos: pos,\n\t}\n\n\t// Parse PRIMARY KEY clause (optional)\n\tif p.matchKeyword(KeywordPrimary) {\n\t\tprimaryKey, err := p.parseDictionaryPrimaryKeyClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tengine.PrimaryKey = primaryKey\n\t}\n\n\t// Parse engine clauses (SOURCE, LIFETIME, LAYOUT, RANGE, SETTINGS)\n\tfor {\n\t\tswitch {\n\t\tcase p.matchKeyword(KeywordSource):\n\t\t\tif engine.Source != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate SOURCE clause\")\n\t\t\t}\n\t\t\tsource, err := p.parseDictionarySourceClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengine.Source = source\n\t\tcase p.matchKeyword(KeywordLifetime):\n\t\t\tif engine.Lifetime != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate LIFETIME clause\")\n\t\t\t}\n\t\t\tlifetime, err := p.parseDictionaryLifetimeClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengine.Lifetime = lifetime\n\t\tcase p.matchKeyword(KeywordLayout):\n\t\t\tif engine.Layout != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate LAYOUT clause\")\n\t\t\t}\n\t\t\tlayout, err := p.parseDictionaryLayoutClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengine.Layout = layout\n\t\tcase p.matchKeyword(KeywordRange):\n\t\t\tif engine.Range != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate RANGE clause\")\n\t\t\t}\n\t\t\trangeClause, err := p.parseDictionaryRangeClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengine.Range = rangeClause\n\t\tcase p.matchKeyword(KeywordSettings):\n\t\t\tif engine.Settings != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate SETTINGS clause\")\n\t\t\t}\n\t\t\tsettings, err := p.parseDictionarySettingsClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tengine.Settings = settings\n\t\tdefault:\n\t\t\t// No more engine clauses\n\t\t\tif engine.Source == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"SOURCE clause is required for dictionary\")\n\t\t\t}\n\t\t\treturn engine, nil\n\t\t}\n\t}\n}\n\nfunc (p *Parser) parseDictionaryPrimaryKeyClause(pos Pos) (*DictionaryPrimaryKeyClause, error) {\n\tif err := p.expectKeyword(KeywordPrimary); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordKey); err != nil {\n\t\treturn nil, err\n\t}\n\n\tkeys, err := p.parseColumnExprList(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DictionaryPrimaryKeyClause{\n\t\tPrimaryKeyPos: pos,\n\t\tKeys:          keys,\n\t\tRParenPos:     keys.End() - 1,\n\t}, nil\n}\n\nfunc (p *Parser) parseDictionarySourceClause(pos Pos) (*DictionarySourceClause, error) {\n\tif err := p.expectKeyword(KeywordSource); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tsourceName, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar args []*DictionaryArgExpr\n\t// Parse optional arguments\n\tfor !p.matchTokenKind(TokenKindRParen) {\n\t\targ, err := p.parseDictionaryArgExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targs = append(args, arg)\n\n\t\t// If there's no right paren, we expect another arg (no comma needed)\n\t\tif p.matchTokenKind(TokenKindRParen) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\trParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DictionarySourceClause{\n\t\tSourcePos: pos,\n\t\tSource:    sourceName,\n\t\tArgs:      args,\n\t\tRParenPos: rParenPos,\n\t}, nil\n}\n\nfunc (p *Parser) parseDictionaryArgExpr(pos Pos) (*DictionaryArgExpr, error) {\n\tname, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar value Expr\n\t// Parse the value part\n\tswitch {\n\tcase p.matchTokenKind(TokenKindString):\n\t\tliteral, err := p.parseLiteral(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue = literal\n\tcase p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat):\n\t\tliteral, err := p.parseLiteral(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue = literal\n\tcase p.matchTokenKind(TokenKindIdent):\n\t\tident, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// Check if it's followed by optional parentheses\n\t\tif p.matchTokenKind(TokenKindLParen) {\n\t\t\t_ = p.lexer.consumeToken() // consume (\n\t\t\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tvalue = &FunctionExpr{\n\t\t\t\tName: ident,\n\t\t\t}\n\t\t} else {\n\t\t\tvalue = ident\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected identifier, string or number in dictionary argument, got %s\", p.lastTokenKind())\n\t}\n\n\treturn &DictionaryArgExpr{\n\t\tArgPos: pos,\n\t\tName:   name,\n\t\tValue:  value,\n\t}, nil\n}\n\nfunc (p *Parser) parseDictionaryLifetimeClause(pos Pos) (*DictionaryLifetimeClause, error) {\n\tif err := p.expectKeyword(KeywordLifetime); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tlifetime := &DictionaryLifetimeClause{\n\t\tLifetimePos: pos,\n\t}\n\n\t// Check for MIN/MAX form\n\tif p.matchKeyword(KeywordMin) || p.matchKeyword(KeywordMax) {\n\t\tisMinFirst := p.matchKeyword(KeywordMin)\n\t\t_ = p.lexer.consumeToken() // consume MIN or MAX\n\n\t\tfirst, err := p.parseNumber(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Expect the other keyword\n\t\tif isMinFirst {\n\t\t\tif err := p.expectKeyword(KeywordMax); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\tif err := p.expectKeyword(KeywordMin); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tsecond, err := p.parseNumber(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif isMinFirst {\n\t\t\tlifetime.Min = first\n\t\t\tlifetime.Max = second\n\t\t} else {\n\t\t\tlifetime.Min = second\n\t\t\tlifetime.Max = first\n\t\t}\n\t} else {\n\t\t// Simple form: LIFETIME(value)\n\t\tvalue, err := p.parseNumber(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlifetime.Value = value\n\t}\n\n\trParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\tlifetime.RParenPos = rParenPos\n\n\treturn lifetime, nil\n}\n\nfunc (p *Parser) parseDictionaryLayoutClause(pos Pos) (*DictionaryLayoutClause, error) {\n\tif err := p.expectKeyword(KeywordLayout); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tlayoutName, err := p.parseIdent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar args []*DictionaryArgExpr\n\t// Parse optional arguments\n\tfor !p.matchTokenKind(TokenKindRParen) {\n\t\targ, err := p.parseDictionaryArgExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targs = append(args, arg)\n\n\t\t// If there's no right paren, we expect another arg (no comma needed)\n\t\tif p.matchTokenKind(TokenKindRParen) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\trParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DictionaryLayoutClause{\n\t\tLayoutPos: pos,\n\t\tLayout:    layoutName,\n\t\tArgs:      args,\n\t\tRParenPos: rParenPos,\n\t}, nil\n}\n\nfunc (p *Parser) parseDictionaryRangeClause(pos Pos) (*DictionaryRangeClause, error) {\n\tif err := p.expectKeyword(KeywordRange); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\trangeClause := &DictionaryRangeClause{\n\t\tRangePos: pos,\n\t}\n\n\t// Parse MIN identifier MAX identifier or MAX identifier MIN identifier\n\tif p.matchKeyword(KeywordMin) {\n\t\tif err := p.expectKeyword(KeywordMin); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmin, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := p.expectKeyword(KeywordMax); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmax, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trangeClause.Min = min\n\t\trangeClause.Max = max\n\t} else if p.matchKeyword(KeywordMax) {\n\t\tif err := p.expectKeyword(KeywordMax); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmax, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := p.expectKeyword(KeywordMin); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmin, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trangeClause.Min = min\n\t\trangeClause.Max = max\n\t} else {\n\t\treturn nil, fmt.Errorf(\"expected MIN or MAX in RANGE clause\")\n\t}\n\n\trParenPos := p.Pos()\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\trangeClause.RParenPos = rParenPos\n\n\treturn rangeClause, nil\n}\n\nfunc (p *Parser) parseDictionarySettingsClause(pos Pos) (*SettingsClause, error) {\n\tif err := p.expectKeyword(KeywordSettings); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectTokenKind(TokenKindLParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\tsettings := &SettingsClause{SettingsPos: pos, ListEnd: pos}\n\titems := make([]*SettingExpr, 0)\n\t// Parse first setting\n\texpr, err := p.parseSettingsExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\titems = append(items, expr)\n\n\t// Parse additional settings\n\tfor p.tryConsumeTokenKind(TokenKindComma) != nil {\n\t\texpr, err := p.parseSettingsExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, expr)\n\t}\n\n\tif len(items) > 0 {\n\t\tsettings.ListEnd = items[len(items)-1].End()\n\t}\n\tsettings.Items = items\n\n\tif err := p.expectTokenKind(TokenKindRParen); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn settings, nil\n}\n"
  },
  {
    "path": "parser/parser_test.go",
    "content": "package parser\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sebdah/goldie/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar runCompatible = flag.Bool(\"compatible\", false, \"run compatible test\")\n\nfunc TestParser_Compatible(t *testing.T) {\n\tif !*runCompatible {\n\t\tt.Skip(\"Compatible test runs only if -compatible is set\")\n\t}\n\tdir := \"./testdata/query/compatible/1_stateful\"\n\tentries, err := os.ReadDir(dir)\n\tif err != nil {\n\t\trequire.NoError(t, err)\n\t}\n\n\tfor _, entry := range entries {\n\t\tif !strings.HasSuffix(entry.Name(), \".sql\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tt.Run(entry.Name(), func(t *testing.T) {\n\t\t\tfileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name()))\n\t\t\trequire.NoError(t, err)\n\t\t\tparser := Parser{\n\t\t\t\tlexer: NewLexer(string(fileBytes)),\n\t\t\t}\n\t\t\t_, err = parser.ParseStmts()\n\t\t\trequire.NoError(t, err)\n\t\t})\n\t}\n}\n\nfunc TestParser_ParseStatements(t *testing.T) {\n\tfor _, dir := range []string{\"./testdata/dml\", \"./testdata/ddl\", \"./testdata/query\", \"./testdata/basic\"} {\n\t\toutputDir := dir + \"/output\"\n\t\tentries, err := os.ReadDir(dir)\n\t\tif err != nil {\n\t\t\trequire.NoError(t, err)\n\t\t}\n\t\tfor _, entry := range entries {\n\t\t\tif !strings.HasSuffix(entry.Name(), \".sql\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.Run(entry.Name(), func(t *testing.T) {\n\t\t\t\tfileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name()))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tparser := Parser{\n\t\t\t\t\tlexer: NewLexer(string(fileBytes)),\n\t\t\t\t}\n\t\t\t\tstmts, err := parser.ParseStmts()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\toutputBytes, _ := json.MarshalIndent(stmts, \"\", \"  \")\n\t\t\t\tg := goldie.New(t,\n\t\t\t\t\tgoldie.WithNameSuffix(\".golden.json\"),\n\t\t\t\t\tgoldie.WithDiffEngine(goldie.ColoredDiff),\n\t\t\t\t\tgoldie.WithFixtureDir(outputDir))\n\t\t\t\tg.Assert(t, entry.Name(), outputBytes)\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc TestParser_Format(t *testing.T) {\n\tfor _, dir := range []string{\"./testdata/dml\", \"./testdata/ddl\", \"./testdata/query\", \"./testdata/basic\"} {\n\t\toutputDir := dir + \"/format\"\n\n\t\tentries, err := os.ReadDir(dir)\n\t\tif err != nil {\n\t\t\trequire.NoError(t, err)\n\t\t}\n\t\tfor _, entry := range entries {\n\t\t\tif !strings.HasSuffix(entry.Name(), \".sql\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.Run(entry.Name(), func(t *testing.T) {\n\t\t\t\tfileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name()))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tparser := Parser{\n\t\t\t\t\tlexer: NewLexer(string(fileBytes)),\n\t\t\t\t}\n\t\t\t\tstmts, err := parser.ParseStmts()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tvar builder strings.Builder\n\t\t\t\tbuilder.WriteString(\"-- Origin SQL:\\n\")\n\t\t\t\tbuilder.Write(fileBytes)\n\t\t\t\tbuilder.WriteString(\"\\n\\n-- Format SQL:\\n\")\n\t\t\t\tvar formatSQLBuilder strings.Builder\n\t\t\t\tfor _, stmt := range stmts {\n\t\t\t\t\tformatSQLBuilder.WriteString(Format(stmt))\n\t\t\t\t\tformatSQLBuilder.WriteByte(';')\n\t\t\t\t\tformatSQLBuilder.WriteByte('\\n')\n\t\t\t\t}\n\t\t\t\tformatSQL := formatSQLBuilder.String()\n\t\t\t\tbuilder.WriteString(formatSQL)\n\t\t\t\tvalidFormatSQL(t, formatSQL)\n\t\t\t\tg := goldie.New(t,\n\t\t\t\t\tgoldie.WithNameSuffix(\"\"),\n\t\t\t\t\tgoldie.WithDiffEngine(goldie.ColoredDiff),\n\t\t\t\t\tgoldie.WithFixtureDir(outputDir))\n\t\t\t\tg.Assert(t, entry.Name(), []byte(builder.String()))\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc TestParser_FormatBeautify(t *testing.T) {\n\tfor _, dir := range []string{\"./testdata/dml\", \"./testdata/ddl\", \"./testdata/query\", \"./testdata/basic\"} {\n\t\toutputDir := dir + \"/format/beautify\"\n\n\t\tentries, err := os.ReadDir(dir)\n\t\tif err != nil {\n\t\t\trequire.NoError(t, err)\n\t\t}\n\t\tfor _, entry := range entries {\n\t\t\tif !strings.HasSuffix(entry.Name(), \".sql\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.Run(entry.Name(), func(t *testing.T) {\n\t\t\t\tfileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name()))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tparser := Parser{\n\t\t\t\t\tlexer: NewLexer(string(fileBytes)),\n\t\t\t\t}\n\t\t\t\tstmts, err := parser.ParseStmts()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tvar builder strings.Builder\n\t\t\t\tbuilder.WriteString(\"-- Origin SQL:\\n\")\n\t\t\t\tbuilder.Write(fileBytes)\n\t\t\t\tbuilder.WriteString(\"\\n\\n-- Beautify SQL:\\n\")\n\t\t\t\tfor _, stmt := range stmts {\n\t\t\t\t\tformatter := NewFormatter()\n\t\t\t\t\tformatter.WithBeautify()\n\t\t\t\t\tformatter.WriteExpr(stmt)\n\t\t\t\t\tbuilder.WriteString(formatter.String())\n\t\t\t\t\tbuilder.WriteByte(';')\n\t\t\t\t\tbuilder.WriteByte('\\n')\n\t\t\t\t}\n\t\t\t\tg := goldie.New(t,\n\t\t\t\t\tgoldie.WithNameSuffix(\"\"),\n\t\t\t\t\tgoldie.WithDiffEngine(goldie.ColoredDiff),\n\t\t\t\t\tgoldie.WithFixtureDir(outputDir))\n\t\t\t\tg.Assert(t, entry.Name(), []byte(builder.String()))\n\t\t\t})\n\t\t}\n\t}\n}\n\n// validFormatSQL Verify that the format sql can be re-parsed with consistent results\nfunc validFormatSQL(t *testing.T, sql string) {\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\tvar builder strings.Builder\n\tfor _, stmt := range stmts {\n\t\tbuilder.WriteString(Format(stmt))\n\t\tbuilder.WriteByte(';')\n\t\tbuilder.WriteByte('\\n')\n\t}\n\trequire.Equal(t, sql, builder.String())\n}\n\nfunc TestParser_InvalidSyntax(t *testing.T) {\n\tinvalidSQLs := []string{\n\t\t\"SELECT * FROM\",\n\t\t// WITH FILL error cases\n\t\t\"SELECT n FROM t ORDER BY n WITH\",                             // WITH without FILL\n\t\t\"SELECT n FROM t ORDER BY n FILL\",                             // FILL without WITH\n\t\t\"SELECT n FROM t ORDER BY n WITH FILL FROM\",                   // FROM without value\n\t\t\"SELECT n FROM t ORDER BY n WITH FILL TO\",                     // TO without value\n\t\t\"SELECT n FROM t ORDER BY n WITH FILL STEP\",                   // STEP without value\n\t\t\"SELECT n FROM t ORDER BY n WITH FILL STALENESS\",              // STALENESS without value\n\t\t\"SELECT n FROM t ORDER BY n WITH FILL INTERPOLATE (x\",         // Missing closing paren\n\t\t\"SELECT n FROM t ORDER BY n WITH FILL INTERPOLATE x AS x + 1\", // Missing parens around column list\n\t\t\"ALTER TABLE foo_mv MODIFY QUERY AS SELECT * FROM baz\",        // MODIFY QUERY followed by an invalid query\n\t\t// Invalid ARRAY JOIN types (only ARRAY JOIN, LEFT ARRAY JOIN, and INNER ARRAY JOIN are valid)\n\t\t\"SELECT * FROM t RIGHT ARRAY JOIN arr AS a\", // RIGHT ARRAY JOIN not supported\n\t\t\"SELECT * FROM t FULL ARRAY JOIN arr AS a\",  // FULL ARRAY JOIN not supported\n\t\t\"00e1d\", // invalid number that leaves lastToken nil\n\t}\n\tfor _, sql := range invalidSQLs {\n\t\tparser := NewParser(sql)\n\t\t_, err := parser.ParseStmts()\n\t\trequire.Error(t, err, \"Expected error for SQL: %s\", sql)\n\t}\n}\n"
  },
  {
    "path": "parser/parser_view.go",
    "content": "package parser\n\nimport \"fmt\"\n\n// parseCreateMaterializedView parses a CREATE MATERIALIZED VIEW statement.\n//\n// The syntax is as follows:\n// CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]\n// REFRESH EVERY|AFTER interval [OFFSET interval]\n// [RANDOMIZE FOR interval]\n// [DEPENDS ON [db.]name [, [db.]name [, ...]]]\n// [SETTINGS name = value [, name = value [, ...]]]\n// [APPEND]\n// [TO[db.]name] [(columns)] [ENGINE = engine]\n// [EMPTY]\n// [DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | NONE }]\n// AS SELECT ...\n// [COMMENT 'comment']\nfunc (p *Parser) parseCreateMaterializedView(pos Pos) (*CreateMaterializedView, error) {\n\tif err := p.expectKeyword(KeywordMaterialized); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := p.expectKeyword(KeywordView); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreateMaterializedView := &CreateMaterializedView{CreatePos: pos}\n\n\t// parse IF NOT EXISTS clause if exists\n\tvar err error\n\tcreateMaterializedView.IfNotExists, err = p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateMaterializedView.Name = tableIdentifier\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateMaterializedView.OnCluster = onCluster\n\n\trefreshExpr, err := p.tryParseRefreshExpr(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateMaterializedView.Refresh = refreshExpr\n\n\tif p.tryConsumeKeywords(KeywordRandomize, KeywordFor) {\n\t\trandomizeFor, err := p.parseInterval(false)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateMaterializedView.RandomizeFor = randomizeFor\n\t}\n\tif p.tryConsumeKeywords(KeywordDepends, KeywordOn) {\n\t\tdependsOnTables := make([]*TableIdentifier, 0)\n\t\ttable, err := p.parseTableIdentifier(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdependsOnTables = append(dependsOnTables, table)\n\t\tfor p.matchTokenKind(TokenKindComma) {\n\t\t\ttable, err := p.parseTableIdentifier(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdependsOnTables = append(dependsOnTables, table)\n\t\t}\n\t\tcreateMaterializedView.DependsOn = dependsOnTables\n\t}\n\tsettings, err := p.tryParseSettingsClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateMaterializedView.Settings = settings\n\tcreateMaterializedView.HasAppend = p.tryConsumeKeywords(KeywordAppend)\n\n\tswitch {\n\tcase p.matchKeyword(KeywordTo):\n\t\tdestination, err := p.parseDestinationClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateMaterializedView.Destination = destination\n\t\tcreateMaterializedView.StatementEnd = destination.End()\n\t\tif p.matchTokenKind(TokenKindLParen) {\n\t\t\ttableSchema, err := p.parseTableSchemaClause(p.Pos())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcreateMaterializedView.Destination.TableSchema = tableSchema\n\t\t}\n\tcase p.matchKeyword(KeywordEngine):\n\t\tengineExpr, err := p.parseEngineExpr(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateMaterializedView.Engine = engineExpr\n\t\tcreateMaterializedView.StatementEnd = engineExpr.End()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected token: %q, expected TO or ENGINE\", p.lastTokenKind())\n\t}\n\tcreateMaterializedView.HasEmpty = p.tryConsumeKeywords(KeywordEmpty)\n\n\t// Parse DEFINER clause\n\tif p.tryConsumeKeywords(KeywordDefiner) {\n\t\tif err := p.expectTokenKind(TokenKindSingleEQ); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefiner, err := p.parseIdent()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateMaterializedView.Definer = definer\n\t}\n\n\t// Parse SQL SECURITY clause\n\tif p.tryConsumeKeywords(KeywordSQL, KeywordSecurity) {\n\t\tif !p.matchOneOfKeywords(KeywordDefiner, KeywordNone) {\n\t\t\treturn nil, fmt.Errorf(\"expected DEFINER or NONE after SQL SECURITY, got %q\", p.lastTokenKind())\n\t\t}\n\t\tcreateMaterializedView.SQLSecurity = p.last().String\n\t\t_ = p.lexer.consumeToken()\n\t}\n\n\t// Check for POPULATE before AS SELECT - only valid with ENGINE and no Destination\n\tif p.tryConsumeKeywords(KeywordPopulate) {\n\t\tif createMaterializedView.Destination != nil {\n\t\t\treturn nil, fmt.Errorf(\"POPULATE is only allowed when using ENGINE, not with TO clause\")\n\t\t}\n\t\tif createMaterializedView.Engine == nil {\n\t\t\treturn nil, fmt.Errorf(\"POPULATE requires ENGINE to be specified\")\n\t\t}\n\t\tcreateMaterializedView.Populate = true\n\t\tcreateMaterializedView.StatementEnd = p.Pos()\n\t}\n\n\t// COMMENT can appear either before or after AS SELECT.\n\t// ClickHouse 26.2+ outputs COMMENT before AS SELECT in SHOW CREATE TABLE,\n\t// while 25.8 outputs it after AS SELECT.\n\tcomment, err := p.tryParseComment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateMaterializedView.Comment = comment\n\n\tif p.tryConsumeKeywords(KeywordAs) {\n\t\tsubQuery, err := p.parseSubQuery(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateMaterializedView.SubQuery = subQuery\n\t\tcreateMaterializedView.StatementEnd = subQuery.End()\n\t}\n\n\t// Also try parsing COMMENT after AS SELECT (ClickHouse 25.x format)\n\tif createMaterializedView.Comment == nil {\n\t\tcomment, err = p.tryParseComment()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateMaterializedView.Comment = comment\n\t}\n\treturn createMaterializedView, nil\n}\n\nfunc (p *Parser) tryParseRefreshExpr(pos Pos) (*RefreshExpr, error) {\n\tif !p.tryConsumeKeywords(KeywordRefresh) {\n\t\treturn nil, nil // nolint\n\t}\n\n\t// REFRESH EVERY|AFTER interval\n\trefreshExpr := &RefreshExpr{RefreshPos: pos}\n\tif !p.matchOneOfKeywords(KeywordEvery, KeywordAfter) {\n\t\treturn nil, fmt.Errorf(\"expected EVERY or AFTER, but got %q\", p.lastTokenKind())\n\t}\n\trefreshExpr.Frequency = p.last().String\n\t_ = p.lexer.consumeToken()\n\n\tinterval, err := p.parseInterval(false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trefreshExpr.Interval = interval\n\n\t// [OFFSET interval]\n\tif p.tryConsumeKeywords(KeywordOffset) {\n\t\toffset, err := p.parseInterval(false)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trefreshExpr.Offset = offset\n\t}\n\n\treturn refreshExpr, nil\n}\n\n// (ATTACH | CREATE) (OR REPLACE)? VIEW (IF NOT EXISTS)? tableIdentifier uuidClause? clusterClause? tableSchemaClause? subqueryClause\nfunc (p *Parser) parseCreateView(pos Pos, orReplace bool) (*CreateView, error) {\n\tcreateView := &CreateView{CreatePos: pos, OrReplace: orReplace}\n\tif err := p.expectKeyword(KeywordView); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar err error\n\tcreateView.IfNotExists, err = p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateView.Name = tableIdentifier\n\n\tuuid, err := p.tryParseUUID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateView.UUID = uuid\n\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateView.OnCluster = onCluster\n\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\ttableSchema, err := p.parseTableSchemaClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateView.TableSchema = tableSchema\n\t}\n\n\t// parse COMMENT clause if exists (before AS SELECT)\n\tcomment, err := p.tryParseComment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateView.Comment = comment\n\n\tif p.tryConsumeKeywords(KeywordAs) {\n\t\tsubQuery, err := p.parseSubQuery(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateView.SubQuery = subQuery\n\t\tcreateView.StatementEnd = subQuery.End()\n\t}\n\n\treturn createView, nil\n}\n\n// # CreateLiveViewStmt\n// (ATTACH | CREATE) LIVE VIEW (IF NOT EXISTS)? tableIdentifier uuidClause?\n// clusterClause? (WITH TIMEOUT DECIMAL_LITERAL?)? destinationClause? tableSchemaClause? subqueryClause\nfunc (p *Parser) parseCreateLiveView(pos Pos) (*CreateLiveView, error) {\n\tif err := p.expectKeyword(KeywordLive); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.expectKeyword(KeywordView); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreateLiveView := &CreateLiveView{CreatePos: pos}\n\t// parse IF NOT EXISTS clause if exists\n\tvar err error\n\tcreateLiveView.IfNotExists, err = p.tryParseIfNotExists()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttableIdentifier, err := p.parseTableIdentifier(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateLiveView.Name = tableIdentifier\n\n\t// try parse UUID clause if exists\n\tuuid, err := p.tryParseUUID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateLiveView.UUID = uuid\n\t// parse ON CLUSTER clause if exists\n\tonCluster, err := p.tryParseClusterClause(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateLiveView.OnCluster = onCluster\n\n\twithTimeout, err := p.tryParseWithTimeout(p.Pos())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcreateLiveView.WithTimeout = withTimeout\n\n\tif p.matchKeyword(KeywordTo) {\n\t\tdestination, err := p.parseDestinationClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateLiveView.Destination = destination\n\t}\n\n\tif p.matchTokenKind(TokenKindLParen) {\n\t\ttableSchema, err := p.parseTableSchemaClause(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateLiveView.TableSchema = tableSchema\n\t}\n\n\tif p.tryConsumeKeywords(KeywordAs) {\n\t\tsubQuery, err := p.parseSubQuery(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcreateLiveView.SubQuery = subQuery\n\t\tcreateLiveView.StatementEnd = subQuery.End()\n\t}\n\n\treturn createLiveView, nil\n}\n\nfunc (p *Parser) tryParseWithTimeout(pos Pos) (*WithTimeoutClause, error) {\n\tif !p.tryConsumeKeywords(KeywordWith) {\n\t\treturn nil, nil // nolint\n\t}\n\tif err := p.expectKeyword(KeywordTimeout); err != nil {\n\t\treturn nil, err\n\t}\n\n\twithTimeout := &WithTimeoutClause{WithTimeoutPos: pos}\n\n\tif p.matchTokenKind(TokenKindInt) {\n\t\tdecimalNumber, err := p.parseDecimal(p.Pos())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\twithTimeout.Number = decimalNumber\n\t}\n\n\treturn withTimeout, nil\n}\n"
  },
  {
    "path": "parser/set.go",
    "content": "package parser\n\ntype Set[T comparable] struct {\n\tm map[T]struct{}\n}\n\nfunc NewSet[T comparable](members ...T) *Set[T] {\n\tm := make(map[T]struct{})\n\tfor _, member := range members {\n\t\tm[member] = struct{}{}\n\t}\n\treturn &Set[T]{m: m}\n}\n\nfunc (s *Set[T]) Add(member T) {\n\ts.m[member] = struct{}{}\n}\n\nfunc (s *Set[T]) Remove(member T) {\n\tdelete(s.m, member)\n}\n\nfunc (s *Set[T]) Contains(member T) bool {\n\t_, ok := s.m[member]\n\treturn ok\n}\n\nfunc (s *Set[T]) Members() []T {\n\tmembers := make([]T, 0, len(s.m))\n\tfor member := range s.m {\n\t\tmembers = append(members, member)\n\t}\n\treturn members\n}\n"
  },
  {
    "path": "parser/set_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestSet(t *testing.T) {\n\ts := NewSet[int](1, 2, 3)\n\n\tif !s.Contains(1) {\n\t\tt.Errorf(\"Set should contain 1\")\n\t}\n\n\tif s.Contains(4) {\n\t\tt.Errorf(\"Set should not contain 4\")\n\t}\n\n\ts.Add(4)\n\n\tif !s.Contains(4) {\n\t\tt.Errorf(\"Set should contain 4\")\n\t}\n\n\ts.Remove(4)\n\n\tif s.Contains(4) {\n\t\tt.Errorf(\"Set should not contain 4\")\n\t}\n\n\trequire.Equal(t, 3, len(s.Members()))\n}\n"
  },
  {
    "path": "parser/testdata/basic/format/beautify/quantile_functions.sql",
    "content": "-- Origin SQL:\nSELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x);\n\n\n-- Beautify SQL:\nSELECT\n  quantile(0.9)(x),\n  quantiles(0.5, 0.9)(x);\n"
  },
  {
    "path": "parser/testdata/basic/format/beautify/set_statement.sql",
    "content": "-- Origin SQL:\nSET allow_suspicious_low_cardinality_types = true;\n\nSET max_block_size = 65536;\n\nSET output_format_json_quote_64bit_integers = 'true';\n\nSET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;\n\nSET allow_experimental_analyzer = true;\n\n\n-- Beautify SQL:\nSET allow_suspicious_low_cardinality_types=true;\nSET max_block_size=65536;\nSET output_format_json_quote_64bit_integers='true';\nSET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false;\nSET allow_experimental_analyzer=true;\n"
  },
  {
    "path": "parser/testdata/basic/format/beautify/settings_statement.sql",
    "content": "-- Origin SQL:\nSETTINGS allow_suspicious_low_cardinality_types = true;\n\nSETTINGS max_block_size = 65536;\n\nSETTINGS output_format_json_quote_64bit_integers = 'true';\n\nSETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;\n\nSETTINGS allow_experimental_analyzer = true;\n\n\n-- Beautify SQL:\nSET allow_suspicious_low_cardinality_types=true;\nSET max_block_size=65536;\nSET output_format_json_quote_64bit_integers='true';\nSET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false;\nSET allow_experimental_analyzer=true;\n"
  },
  {
    "path": "parser/testdata/basic/format/beautify/use_database.sql",
    "content": "-- Origin SQL:\nUSE test;\n\n-- Beautify SQL:\nUSE test;\n"
  },
  {
    "path": "parser/testdata/basic/format/quantile_functions.sql",
    "content": "-- Origin SQL:\nSELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x);\n\n\n-- Format SQL:\nSELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x);\n"
  },
  {
    "path": "parser/testdata/basic/format/set_statement.sql",
    "content": "-- Origin SQL:\nSET allow_suspicious_low_cardinality_types = true;\n\nSET max_block_size = 65536;\n\nSET output_format_json_quote_64bit_integers = 'true';\n\nSET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;\n\nSET allow_experimental_analyzer = true;\n\n\n-- Format SQL:\nSET allow_suspicious_low_cardinality_types=true;\nSET max_block_size=65536;\nSET output_format_json_quote_64bit_integers='true';\nSET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false;\nSET allow_experimental_analyzer=true;\n"
  },
  {
    "path": "parser/testdata/basic/format/settings_statement.sql",
    "content": "-- Origin SQL:\nSETTINGS allow_suspicious_low_cardinality_types = true;\n\nSETTINGS max_block_size = 65536;\n\nSETTINGS output_format_json_quote_64bit_integers = 'true';\n\nSETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;\n\nSETTINGS allow_experimental_analyzer = true;\n\n\n-- Format SQL:\nSET allow_suspicious_low_cardinality_types=true;\nSET max_block_size=65536;\nSET output_format_json_quote_64bit_integers='true';\nSET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false;\nSET allow_experimental_analyzer=true;\n"
  },
  {
    "path": "parser/testdata/basic/format/use_database.sql",
    "content": "-- Origin SQL:\nUSE test;\n\n-- Format SQL:\nUSE test;\n"
  },
  {
    "path": "parser/testdata/basic/output/quantile_functions.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 43,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"quantile\",\n            \"QuoteType\": 1,\n            \"NamePos\": 7,\n            \"NameEnd\": 15\n          },\n          \"Params\": {\n            \"LeftParenPos\": 15,\n            \"RightParenPos\": 19,\n            \"Items\": {\n              \"ListPos\": 16,\n              \"ListEnd\": 19,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"NumPos\": 16,\n                    \"NumEnd\": 19,\n                    \"Literal\": \"0.9\",\n                    \"Base\": 10\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": {\n              \"Distinct\": false,\n              \"LeftParenPos\": 20,\n              \"RightParenPos\": 22,\n              \"Items\": [\n                {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 21,\n                  \"NameEnd\": 22\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"quantiles\",\n            \"QuoteType\": 1,\n            \"NamePos\": 25,\n            \"NameEnd\": 34\n          },\n          \"Params\": {\n            \"LeftParenPos\": 34,\n            \"RightParenPos\": 43,\n            \"Items\": {\n              \"ListPos\": 35,\n              \"ListEnd\": 43,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"NumPos\": 35,\n                    \"NumEnd\": 38,\n                    \"Literal\": \"0.5\",\n                    \"Base\": 10\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"NumPos\": 40,\n                    \"NumEnd\": 43,\n                    \"Literal\": \"0.9\",\n                    \"Base\": 10\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": {\n              \"Distinct\": false,\n              \"LeftParenPos\": 44,\n              \"RightParenPos\": 46,\n              \"Items\": [\n                {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 45,\n                  \"NameEnd\": 46\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/basic/output/set_statement.sql.golden.json",
    "content": "[\n  {\n    \"SetPos\": 0,\n    \"Settings\": {\n      \"SettingsPos\": 4,\n      \"ListEnd\": 49,\n      \"Items\": [\n        {\n          \"SettingsPos\": 4,\n          \"Name\": {\n            \"Name\": \"allow_suspicious_low_cardinality_types\",\n            \"QuoteType\": 1,\n            \"NamePos\": 4,\n            \"NameEnd\": 42\n          },\n          \"Expr\": {\n            \"LiteralPos\": 45,\n            \"LiteralEnd\": 49,\n            \"Literal\": \"true\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 52,\n    \"Settings\": {\n      \"SettingsPos\": 56,\n      \"ListEnd\": 78,\n      \"Items\": [\n        {\n          \"SettingsPos\": 56,\n          \"Name\": {\n            \"Name\": \"max_block_size\",\n            \"QuoteType\": 1,\n            \"NamePos\": 56,\n            \"NameEnd\": 70\n          },\n          \"Expr\": {\n            \"NumPos\": 73,\n            \"NumEnd\": 78,\n            \"Literal\": \"65536\",\n            \"Base\": 10\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 81,\n    \"Settings\": {\n      \"SettingsPos\": 85,\n      \"ListEnd\": 132,\n      \"Items\": [\n        {\n          \"SettingsPos\": 85,\n          \"Name\": {\n            \"Name\": \"output_format_json_quote_64bit_integers\",\n            \"QuoteType\": 1,\n            \"NamePos\": 85,\n            \"NameEnd\": 124\n          },\n          \"Expr\": {\n            \"LiteralPos\": 128,\n            \"LiteralEnd\": 132,\n            \"Literal\": \"true\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 136,\n    \"Settings\": {\n      \"SettingsPos\": 140,\n      \"ListEnd\": 233,\n      \"Items\": [\n        {\n          \"SettingsPos\": 140,\n          \"Name\": {\n            \"Name\": \"max_threads\",\n            \"QuoteType\": 1,\n            \"NamePos\": 140,\n            \"NameEnd\": 151\n          },\n          \"Expr\": {\n            \"NumPos\": 154,\n            \"NumEnd\": 155,\n            \"Literal\": \"8\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 157,\n          \"Name\": {\n            \"Name\": \"max_memory_usage\",\n            \"QuoteType\": 1,\n            \"NamePos\": 157,\n            \"NameEnd\": 173\n          },\n          \"Expr\": {\n            \"NumPos\": 176,\n            \"NumEnd\": 187,\n            \"Literal\": \"10000000000\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 189,\n          \"Name\": {\n            \"Name\": \"enable_optimize_predicate_expression\",\n            \"QuoteType\": 1,\n            \"NamePos\": 189,\n            \"NameEnd\": 225\n          },\n          \"Expr\": {\n            \"LiteralPos\": 228,\n            \"LiteralEnd\": 233,\n            \"Literal\": \"false\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 236,\n    \"Settings\": {\n      \"SettingsPos\": 240,\n      \"ListEnd\": 274,\n      \"Items\": [\n        {\n          \"SettingsPos\": 240,\n          \"Name\": {\n            \"Name\": \"allow_experimental_analyzer\",\n            \"QuoteType\": 1,\n            \"NamePos\": 240,\n            \"NameEnd\": 267\n          },\n          \"Expr\": {\n            \"LiteralPos\": 270,\n            \"LiteralEnd\": 274,\n            \"Literal\": \"true\"\n          }\n        }\n      ]\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/basic/output/settings_statement.sql.golden.json",
    "content": "[\n  {\n    \"SetPos\": 0,\n    \"Settings\": {\n      \"SettingsPos\": 9,\n      \"ListEnd\": 54,\n      \"Items\": [\n        {\n          \"SettingsPos\": 9,\n          \"Name\": {\n            \"Name\": \"allow_suspicious_low_cardinality_types\",\n            \"QuoteType\": 1,\n            \"NamePos\": 9,\n            \"NameEnd\": 47\n          },\n          \"Expr\": {\n            \"LiteralPos\": 50,\n            \"LiteralEnd\": 54,\n            \"Literal\": \"true\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 57,\n    \"Settings\": {\n      \"SettingsPos\": 66,\n      \"ListEnd\": 88,\n      \"Items\": [\n        {\n          \"SettingsPos\": 66,\n          \"Name\": {\n            \"Name\": \"max_block_size\",\n            \"QuoteType\": 1,\n            \"NamePos\": 66,\n            \"NameEnd\": 80\n          },\n          \"Expr\": {\n            \"NumPos\": 83,\n            \"NumEnd\": 88,\n            \"Literal\": \"65536\",\n            \"Base\": 10\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 91,\n    \"Settings\": {\n      \"SettingsPos\": 100,\n      \"ListEnd\": 147,\n      \"Items\": [\n        {\n          \"SettingsPos\": 100,\n          \"Name\": {\n            \"Name\": \"output_format_json_quote_64bit_integers\",\n            \"QuoteType\": 1,\n            \"NamePos\": 100,\n            \"NameEnd\": 139\n          },\n          \"Expr\": {\n            \"LiteralPos\": 143,\n            \"LiteralEnd\": 147,\n            \"Literal\": \"true\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 151,\n    \"Settings\": {\n      \"SettingsPos\": 160,\n      \"ListEnd\": 253,\n      \"Items\": [\n        {\n          \"SettingsPos\": 160,\n          \"Name\": {\n            \"Name\": \"max_threads\",\n            \"QuoteType\": 1,\n            \"NamePos\": 160,\n            \"NameEnd\": 171\n          },\n          \"Expr\": {\n            \"NumPos\": 174,\n            \"NumEnd\": 175,\n            \"Literal\": \"8\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 177,\n          \"Name\": {\n            \"Name\": \"max_memory_usage\",\n            \"QuoteType\": 1,\n            \"NamePos\": 177,\n            \"NameEnd\": 193\n          },\n          \"Expr\": {\n            \"NumPos\": 196,\n            \"NumEnd\": 207,\n            \"Literal\": \"10000000000\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 209,\n          \"Name\": {\n            \"Name\": \"enable_optimize_predicate_expression\",\n            \"QuoteType\": 1,\n            \"NamePos\": 209,\n            \"NameEnd\": 245\n          },\n          \"Expr\": {\n            \"LiteralPos\": 248,\n            \"LiteralEnd\": 253,\n            \"Literal\": \"false\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 256,\n    \"Settings\": {\n      \"SettingsPos\": 265,\n      \"ListEnd\": 299,\n      \"Items\": [\n        {\n          \"SettingsPos\": 265,\n          \"Name\": {\n            \"Name\": \"allow_experimental_analyzer\",\n            \"QuoteType\": 1,\n            \"NamePos\": 265,\n            \"NameEnd\": 292\n          },\n          \"Expr\": {\n            \"LiteralPos\": 295,\n            \"LiteralEnd\": 299,\n            \"Literal\": \"true\"\n          }\n        }\n      ]\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/basic/output/use_database.sql.golden.json",
    "content": "[\n  {\n    \"UsePos\": 0,\n    \"StatementEnd\": 8,\n    \"Database\": {\n      \"Name\": \"test\",\n      \"QuoteType\": 1,\n      \"NamePos\": 4,\n      \"NameEnd\": 8\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/basic/quantile_functions.sql",
    "content": "SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x);\n"
  },
  {
    "path": "parser/testdata/basic/set_statement.sql",
    "content": "SET allow_suspicious_low_cardinality_types = true;\n\nSET max_block_size = 65536;\n\nSET output_format_json_quote_64bit_integers = 'true';\n\nSET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;\n\nSET allow_experimental_analyzer = true;\n"
  },
  {
    "path": "parser/testdata/basic/settings_statement.sql",
    "content": "SETTINGS allow_suspicious_low_cardinality_types = true;\n\nSETTINGS max_block_size = 65536;\n\nSETTINGS output_format_json_quote_64bit_integers = 'true';\n\nSETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;\n\nSETTINGS allow_experimental_analyzer = true;\n"
  },
  {
    "path": "parser/testdata/basic/use_database.sql",
    "content": "USE test;"
  },
  {
    "path": "parser/testdata/benchdata/posthog_huge_0.sql",
    "content": "  /* user_id:0 request:_snapshot_ */\n  SELECT fill.bin_from_seconds AS bin_from_seconds,\n         results.person_count AS person_count,\n  \n    (SELECT histogram_params.average_conversion_time AS average_conversion_time\n     FROM\n       (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds,\n               ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds,\n               round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time,\n               count() AS sample_count,\n               least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count,\n               ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw,\n               if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n        FROM\n          (SELECT aggregation_target AS aggregation_target,\n                  steps AS steps,\n                  avg(step_1_conversion_time) AS step_1_average_conversion_time_inner,\n                  avg(step_2_conversion_time) AS step_2_average_conversion_time_inner,\n                  median(step_1_conversion_time) AS step_1_median_conversion_time_inner,\n                  median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n           FROM\n             (SELECT aggregation_target AS aggregation_target,\n                     steps AS steps,\n                     max(steps) OVER (PARTITION BY aggregation_target) AS max_steps,\n                                     step_1_conversion_time AS step_1_conversion_time,\n                                     step_2_conversion_time AS step_2_conversion_time\n              FROM\n                (SELECT aggregation_target AS aggregation_target,\n                        timestamp AS timestamp,\n                        step_0 AS step_0,\n                        latest_0 AS latest_0,\n                        step_1 AS step_1,\n                        latest_1 AS latest_1,\n                        step_2 AS step_2,\n                        latest_2 AS latest_2,\n                        if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps,\n                        if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time,\n                        if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                 FROM\n                   (SELECT aggregation_target AS aggregation_target,\n                           timestamp AS timestamp,\n                           step_0 AS step_0,\n                           latest_0 AS latest_0,\n                           step_1 AS step_1,\n                           latest_1 AS latest_1,\n                           step_2 AS step_2,\n                           min(latest_2) OVER (PARTITION BY aggregation_target\n                                               ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                    FROM\n                      (SELECT aggregation_target AS aggregation_target,\n                              timestamp AS timestamp,\n                              step_0 AS step_0,\n                              latest_0 AS latest_0,\n                              step_1 AS step_1,\n                              latest_1 AS latest_1,\n                              step_2 AS step_2,\n                              if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                       FROM\n                         (SELECT aggregation_target AS aggregation_target,\n                                 timestamp AS timestamp,\n                                 step_0 AS step_0,\n                                 latest_0 AS latest_0,\n                                 step_1 AS step_1,\n                                 min(latest_1) OVER (PARTITION BY aggregation_target\n                                                     ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1,\n                                                    step_2 AS step_2,\n                                                    min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                        ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                          FROM\n                            (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp,\n                                    if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target,\n                                    if(equals(e.event, 'step one'), 1, 0) AS step_0,\n                                    if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0,\n                                    if(equals(e.event, 'step two'), 1, 0) AS step_1,\n                                    if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1,\n                                    if(equals(e.event, 'step three'), 1, 0) AS step_2,\n                                    if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                             FROM events AS e\n                             LEFT OUTER JOIN\n                               (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id,\n                                       person_distinct_id_overrides.distinct_id AS distinct_id\n                                FROM person_distinct_id_overrides\n                                WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                GROUP BY person_distinct_id_overrides.distinct_id\n                                HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                             WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                 WHERE ifNull(equals(step_0, 1), 0)))\n           GROUP BY aggregation_target,\n                    steps\n           HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                         and isNull(max(max_steps)))) AS step_runs\n        WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params) AS average_conversion_time\n  FROM\n    (SELECT plus(\n                   (SELECT histogram_params.from_seconds AS from_seconds\n                    FROM\n                      (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                       FROM\n                         (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                          FROM\n                            (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                             FROM\n                               (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                FROM\n                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                  ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                   FROM\n                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                      FROM\n                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                             ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                         FROM\n                                           (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                            FROM events AS e\n                                            LEFT OUTER JOIN\n                                              (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                               FROM person_distinct_id_overrides\n                                               WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                               GROUP BY person_distinct_id_overrides.distinct_id\n                                               HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                            WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                WHERE ifNull(equals(step_0, 1), 0)))\n                          GROUP BY aggregation_target, steps\n                          HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                        and isNull(max(max_steps)))) AS step_runs\n                       WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(floor(divide(minus(step_runs.step_1_average_conversion_time_inner,\n                                                                                                                                            (SELECT histogram_params.from_seconds AS from_seconds\n                                                                                                                                             FROM\n                                                                                                                                               (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                                                FROM\n                                                                                                                                                  (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                                   FROM\n                                                                                                                                                     (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                                      FROM\n                                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                                         FROM\n                                                                                                                                                           (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                           ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                                            FROM\n                                                                                                                                                              (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                                                                                                                                               FROM\n                                                                                                                                                                 (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                         ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                                                      ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                                                  FROM\n                                                                                                                                                                    (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                                                     FROM events AS e\n                                                                                                                                                                     LEFT OUTER JOIN\n                                                                                                                                                                       (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                                                        FROM person_distinct_id_overrides\n                                                                                                                                                                        WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                                                        GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                                                        HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                                                     WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                                                                                                                                         WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                                   GROUP BY aggregation_target, steps\n                                                                                                                                                   HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                                                 and isNull(max(max_steps)))) AS step_runs\n                                                                                                                                                WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params)),\n                                                                                                                                      (SELECT histogram_params.bin_width_seconds AS bin_width_seconds\n                                                                                                                                       FROM\n                                                                                                                                         (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                                          FROM\n                                                                                                                                            (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                             FROM\n                                                                                                                                               (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                                FROM\n                                                                                                                                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                                   FROM\n                                                                                                                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                     ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                                      FROM\n                                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                                                                                                                                         FROM\n                                                                                                                                                           (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                   ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                                                ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                                            FROM\n                                                                                                                                                              (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                                               FROM events AS e\n                                                                                                                                                               LEFT OUTER JOIN\n                                                                                                                                                                 (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                                                  FROM person_distinct_id_overrides\n                                                                                                                                                                  WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                                                  GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                                                  HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                                               WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                                                                                                                                   WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                             GROUP BY aggregation_target, steps\n                                                                                                                                             HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                                           and isNull(max(max_steps)))) AS step_runs\n                                                                                                                                          WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))),\n                                                                                                                         (SELECT histogram_params.bin_width_seconds AS bin_width_seconds\n                                                                                                                          FROM\n                                                                                                                            (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                             FROM\n                                                                                                                               (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                FROM\n                                                                                                                                  (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                   FROM\n                                                                                                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                      FROM\n                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                        ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                         FROM\n                                                                                                                                           (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                                                                                                                            FROM\n                                                                                                                                              (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                      ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                                   ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                               FROM\n                                                                                                                                                 (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                                  FROM events AS e\n                                                                                                                                                  LEFT OUTER JOIN\n                                                                                                                                                    (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                                     FROM person_distinct_id_overrides\n                                                                                                                                                     WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                                     GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                                     HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                                  WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                                                                                                                      WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                GROUP BY aggregation_target, steps\n                                                                                                                                HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                              and isNull(max(max_steps)))) AS step_runs\n                                                                                                                             WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds,\n            count() AS person_count\n     FROM\n       (SELECT aggregation_target AS aggregation_target,\n               steps AS steps,\n               avg(step_1_conversion_time) AS step_1_average_conversion_time_inner,\n               avg(step_2_conversion_time) AS step_2_average_conversion_time_inner,\n               median(step_1_conversion_time) AS step_1_median_conversion_time_inner,\n               median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n        FROM\n          (SELECT aggregation_target AS aggregation_target,\n                  steps AS steps,\n                  max(steps) OVER (PARTITION BY aggregation_target) AS max_steps,\n                                  step_1_conversion_time AS step_1_conversion_time,\n                                  step_2_conversion_time AS step_2_conversion_time\n           FROM\n             (SELECT aggregation_target AS aggregation_target,\n                     timestamp AS timestamp,\n                     step_0 AS step_0,\n                     latest_0 AS latest_0,\n                     step_1 AS step_1,\n                     latest_1 AS latest_1,\n                     step_2 AS step_2,\n                     latest_2 AS latest_2,\n                     if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps,\n                     if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time,\n                     if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n              FROM\n                (SELECT aggregation_target AS aggregation_target,\n                        timestamp AS timestamp,\n                        step_0 AS step_0,\n                        latest_0 AS latest_0,\n                        step_1 AS step_1,\n                        latest_1 AS latest_1,\n                        step_2 AS step_2,\n                        min(latest_2) OVER (PARTITION BY aggregation_target\n                                            ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                 FROM\n                   (SELECT aggregation_target AS aggregation_target,\n                           timestamp AS timestamp,\n                           step_0 AS step_0,\n                           latest_0 AS latest_0,\n                           step_1 AS step_1,\n                           latest_1 AS latest_1,\n                           step_2 AS step_2,\n                           if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                    FROM\n                      (SELECT aggregation_target AS aggregation_target,\n                              timestamp AS timestamp,\n                              step_0 AS step_0,\n                              latest_0 AS latest_0,\n                              step_1 AS step_1,\n                              min(latest_1) OVER (PARTITION BY aggregation_target\n                                                  ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1,\n                                                 step_2 AS step_2,\n                                                 min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                     ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                       FROM\n                         (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp,\n                                 if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target,\n                                 if(equals(e.event, 'step one'), 1, 0) AS step_0,\n                                 if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0,\n                                 if(equals(e.event, 'step two'), 1, 0) AS step_1,\n                                 if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1,\n                                 if(equals(e.event, 'step three'), 1, 0) AS step_2,\n                                 if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                          FROM events AS e\n                          LEFT OUTER JOIN\n                            (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id,\n                                    person_distinct_id_overrides.distinct_id AS distinct_id\n                             FROM person_distinct_id_overrides\n                             WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                             GROUP BY person_distinct_id_overrides.distinct_id\n                             HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                          WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n              WHERE ifNull(equals(step_0, 1), 0)))\n        GROUP BY aggregation_target,\n                 steps\n        HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                      and isNull(max(max_steps)))) AS step_runs\n     GROUP BY bin_from_seconds) AS results\n  RIGHT OUTER JOIN\n    (SELECT plus(\n                   (SELECT histogram_params.from_seconds AS from_seconds\n                    FROM\n                      (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                       FROM\n                         (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                          FROM\n                            (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                             FROM\n                               (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                FROM\n                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                  ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                   FROM\n                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                      FROM\n                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                             ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                         FROM\n                                           (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                            FROM events AS e\n                                            LEFT OUTER JOIN\n                                              (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                               FROM person_distinct_id_overrides\n                                               WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                               GROUP BY person_distinct_id_overrides.distinct_id\n                                               HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                            WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                WHERE ifNull(equals(step_0, 1), 0)))\n                          GROUP BY aggregation_target, steps\n                          HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                        and isNull(max(max_steps)))) AS step_runs\n                       WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(numbers.number,\n                                                                                                                         (SELECT histogram_params.bin_width_seconds AS bin_width_seconds\n                                                                                                                          FROM\n                                                                                                                            (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                             FROM\n                                                                                                                               (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                FROM\n                                                                                                                                  (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                   FROM\n                                                                                                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                      FROM\n                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                        ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                         FROM\n                                                                                                                                           (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                                                                                                                            FROM\n                                                                                                                                              (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                      ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                                   ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                                                                                                               FROM\n                                                                                                                                                 (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                                  FROM events AS e\n                                                                                                                                                  LEFT OUTER JOIN\n                                                                                                                                                    (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                                     FROM person_distinct_id_overrides\n                                                                                                                                                     WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                                     GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                                     HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                                  WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                                                                                                                      WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                GROUP BY aggregation_target, steps\n                                                                                                                                HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                              and isNull(max(max_steps)))) AS step_runs\n                                                                                                                             WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds\n     FROM numbers(plus(ifNull(\n                                (SELECT histogram_params.bin_count AS bin_count\n                                 FROM\n                                   (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                    FROM\n                                      (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                       FROM\n                                         (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                          FROM\n                                            (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                             FROM\n                                               (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                               ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                FROM\n                                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2\n                                                   FROM\n                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                             ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                          ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2\n                                                      FROM\n                                                        (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                         FROM events AS e\n                                                         LEFT OUTER JOIN\n                                                           (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                            FROM person_distinct_id_overrides\n                                                            WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                            GROUP BY person_distinct_id_overrides.distinct_id\n                                                            HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                         WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))))))\n                                             WHERE ifNull(equals(step_0, 1), 0)))\n                                       GROUP BY aggregation_target, steps\n                                       HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                     and isNull(max(max_steps)))) AS step_runs\n                                    WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), 0), 1)) AS numbers) AS fill ON equals(results.bin_from_seconds, fill.bin_from_seconds)\n  ORDER BY fill.bin_from_seconds ASC\n  LIMIT 100 SETTINGS readonly=2,\n                     max_execution_time=60,\n                     allow_experimental_object_type=1,\n                     format_csv_allow_double_quotes=0,\n                     max_ast_elements=4000000,\n                     max_expanded_ast_elements=4000000,\n                     max_bytes_before_external_group_by=23622320128,\n                     allow_experimental_analyzer=1"
  },
  {
    "path": "parser/testdata/benchdata/posthog_huge_1.sql",
    "content": "  /* user_id:0 request:_snapshot_ */\n  SELECT fill.bin_from_seconds AS bin_from_seconds,\n         results.person_count AS person_count,\n  \n    (SELECT histogram_params.average_conversion_time AS average_conversion_time\n     FROM\n       (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds,\n               ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds,\n               round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time,\n               count() AS sample_count,\n               least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count,\n               ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw,\n               if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n        FROM\n          (SELECT aggregation_target AS aggregation_target,\n                  steps AS steps,\n                  avg(step_1_conversion_time) AS step_1_average_conversion_time_inner,\n                  avg(step_2_conversion_time) AS step_2_average_conversion_time_inner,\n                  median(step_1_conversion_time) AS step_1_median_conversion_time_inner,\n                  median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n           FROM\n             (SELECT aggregation_target AS aggregation_target,\n                     steps AS steps,\n                     max(steps) OVER (PARTITION BY aggregation_target) AS max_steps,\n                                     step_1_conversion_time AS step_1_conversion_time,\n                                     step_2_conversion_time AS step_2_conversion_time\n              FROM\n                (SELECT aggregation_target AS aggregation_target,\n                        timestamp AS timestamp,\n                        step_0 AS step_0,\n                        latest_0 AS latest_0,\n                        step_1 AS step_1,\n                        latest_1 AS latest_1,\n                        step_2 AS step_2,\n                        latest_2 AS latest_2,\n                        if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps,\n                        if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time,\n                        if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                 FROM\n                   (SELECT aggregation_target AS aggregation_target,\n                           timestamp AS timestamp,\n                           step_0 AS step_0,\n                           latest_0 AS latest_0,\n                           step_1 AS step_1,\n                           min(latest_1) OVER (PARTITION BY aggregation_target\n                                               ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1,\n                                              step_2 AS step_2,\n                                              min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                  ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                    FROM\n                      (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp,\n                              if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target,\n                              if(equals(e.event, 'step one'), 1, 0) AS step_0,\n                              if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0,\n                              if(equals(e.event, 'step two'), 1, 0) AS step_1,\n                              if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1,\n                              if(equals(e.event, 'step three'), 1, 0) AS step_2,\n                              if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                       FROM events AS e\n                       LEFT OUTER JOIN\n                         (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id,\n                                 person_distinct_id_overrides.distinct_id AS distinct_id\n                          FROM person_distinct_id_overrides\n                          WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                          GROUP BY person_distinct_id_overrides.distinct_id\n                          HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                       WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                 WHERE ifNull(equals(step_0, 1), 0)))\n           GROUP BY aggregation_target,\n                    steps\n           HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                         and isNull(max(max_steps)))) AS step_runs\n        WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params) AS average_conversion_time\n  FROM\n    (SELECT plus(\n                   (SELECT histogram_params.from_seconds AS from_seconds\n                    FROM\n                      (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                       FROM\n                         (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                          FROM\n                            (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                             FROM\n                               (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                FROM\n                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                          ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                               ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                   FROM\n                                     (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                      FROM events AS e\n                                      LEFT OUTER JOIN\n                                        (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                         FROM person_distinct_id_overrides\n                                         WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                         GROUP BY person_distinct_id_overrides.distinct_id\n                                         HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                      WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                WHERE ifNull(equals(step_0, 1), 0)))\n                          GROUP BY aggregation_target, steps\n                          HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                        and isNull(max(max_steps)))) AS step_runs\n                       WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(floor(divide(minus(step_runs.step_1_average_conversion_time_inner,\n                                                                                                                                            (SELECT histogram_params.from_seconds AS from_seconds\n                                                                                                                                             FROM\n                                                                                                                                               (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                                                FROM\n                                                                                                                                                  (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                                   FROM\n                                                                                                                                                     (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                                      FROM\n                                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                                         FROM\n                                                                                                                                                           (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                   ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                                        ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                                                                                                                                            FROM\n                                                                                                                                                              (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                                               FROM events AS e\n                                                                                                                                                               LEFT OUTER JOIN\n                                                                                                                                                                 (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                                                  FROM person_distinct_id_overrides\n                                                                                                                                                                  WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                                                  GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                                                  HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                                               WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                                                                                                                                         WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                                   GROUP BY aggregation_target, steps\n                                                                                                                                                   HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                                                 and isNull(max(max_steps)))) AS step_runs\n                                                                                                                                                WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params)),\n                                                                                                                                      (SELECT histogram_params.bin_width_seconds AS bin_width_seconds\n                                                                                                                                       FROM\n                                                                                                                                         (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                                          FROM\n                                                                                                                                            (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                             FROM\n                                                                                                                                               (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                                FROM\n                                                                                                                                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                                   FROM\n                                                                                                                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                             ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                                  ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                                                                                                                                      FROM\n                                                                                                                                                        (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                                         FROM events AS e\n                                                                                                                                                         LEFT OUTER JOIN\n                                                                                                                                                           (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                                            FROM person_distinct_id_overrides\n                                                                                                                                                            WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                                            GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                                            HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                                         WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                                                                                                                                   WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                             GROUP BY aggregation_target, steps\n                                                                                                                                             HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                                           and isNull(max(max_steps)))) AS step_runs\n                                                                                                                                          WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))),\n                                                                                                                         (SELECT histogram_params.bin_width_seconds AS bin_width_seconds\n                                                                                                                          FROM\n                                                                                                                            (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                             FROM\n                                                                                                                               (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                FROM\n                                                                                                                                  (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                   FROM\n                                                                                                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                      FROM\n                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                     ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                                                                                                                         FROM\n                                                                                                                                           (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                            FROM events AS e\n                                                                                                                                            LEFT OUTER JOIN\n                                                                                                                                              (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                               FROM person_distinct_id_overrides\n                                                                                                                                               WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                               GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                               HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                            WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                                                                                                                      WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                GROUP BY aggregation_target, steps\n                                                                                                                                HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                              and isNull(max(max_steps)))) AS step_runs\n                                                                                                                             WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds,\n            count() AS person_count\n     FROM\n       (SELECT aggregation_target AS aggregation_target,\n               steps AS steps,\n               avg(step_1_conversion_time) AS step_1_average_conversion_time_inner,\n               avg(step_2_conversion_time) AS step_2_average_conversion_time_inner,\n               median(step_1_conversion_time) AS step_1_median_conversion_time_inner,\n               median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n        FROM\n          (SELECT aggregation_target AS aggregation_target,\n                  steps AS steps,\n                  max(steps) OVER (PARTITION BY aggregation_target) AS max_steps,\n                                  step_1_conversion_time AS step_1_conversion_time,\n                                  step_2_conversion_time AS step_2_conversion_time\n           FROM\n             (SELECT aggregation_target AS aggregation_target,\n                     timestamp AS timestamp,\n                     step_0 AS step_0,\n                     latest_0 AS latest_0,\n                     step_1 AS step_1,\n                     latest_1 AS latest_1,\n                     step_2 AS step_2,\n                     latest_2 AS latest_2,\n                     if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps,\n                     if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time,\n                     if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n              FROM\n                (SELECT aggregation_target AS aggregation_target,\n                        timestamp AS timestamp,\n                        step_0 AS step_0,\n                        latest_0 AS latest_0,\n                        step_1 AS step_1,\n                        min(latest_1) OVER (PARTITION BY aggregation_target\n                                            ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1,\n                                           step_2 AS step_2,\n                                           min(latest_2) OVER (PARTITION BY aggregation_target\n                                                               ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                 FROM\n                   (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp,\n                           if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target,\n                           if(equals(e.event, 'step one'), 1, 0) AS step_0,\n                           if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0,\n                           if(equals(e.event, 'step two'), 1, 0) AS step_1,\n                           if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1,\n                           if(equals(e.event, 'step three'), 1, 0) AS step_2,\n                           if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                    FROM events AS e\n                    LEFT OUTER JOIN\n                      (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id,\n                              person_distinct_id_overrides.distinct_id AS distinct_id\n                       FROM person_distinct_id_overrides\n                       WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                       GROUP BY person_distinct_id_overrides.distinct_id\n                       HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                    WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n              WHERE ifNull(equals(step_0, 1), 0)))\n        GROUP BY aggregation_target,\n                 steps\n        HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                      and isNull(max(max_steps)))) AS step_runs\n     GROUP BY bin_from_seconds) AS results\n  RIGHT OUTER JOIN\n    (SELECT plus(\n                   (SELECT histogram_params.from_seconds AS from_seconds\n                    FROM\n                      (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                       FROM\n                         (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                          FROM\n                            (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                             FROM\n                               (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                FROM\n                                  (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                          ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                               ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                   FROM\n                                     (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                      FROM events AS e\n                                      LEFT OUTER JOIN\n                                        (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                         FROM person_distinct_id_overrides\n                                         WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                         GROUP BY person_distinct_id_overrides.distinct_id\n                                         HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                      WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                WHERE ifNull(equals(step_0, 1), 0)))\n                          GROUP BY aggregation_target, steps\n                          HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                        and isNull(max(max_steps)))) AS step_runs\n                       WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(numbers.number,\n                                                                                                                         (SELECT histogram_params.bin_width_seconds AS bin_width_seconds\n                                                                                                                          FROM\n                                                                                                                            (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                                                                                                             FROM\n                                                                                                                               (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                                                                                                                FROM\n                                                                                                                                  (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                                                                                                                   FROM\n                                                                                                                                     (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                                                                                                                      FROM\n                                                                                                                                        (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                                                                                                                     ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                                                                                                                         FROM\n                                                                                                                                           (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                                                                                                            FROM events AS e\n                                                                                                                                            LEFT OUTER JOIN\n                                                                                                                                              (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                                                                                                               FROM person_distinct_id_overrides\n                                                                                                                                               WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                                                                                                               GROUP BY person_distinct_id_overrides.distinct_id\n                                                                                                                                               HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                                                                                                            WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                                                                                                                      WHERE ifNull(equals(step_0, 1), 0)))\n                                                                                                                                GROUP BY aggregation_target, steps\n                                                                                                                                HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                                                                                                              and isNull(max(max_steps)))) AS step_runs\n                                                                                                                             WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds\n     FROM numbers(plus(ifNull(\n                                (SELECT histogram_params.bin_count AS bin_count\n                                 FROM\n                                   (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds\n                                    FROM\n                                      (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner\n                                       FROM\n                                         (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time\n                                          FROM\n                                            (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time\n                                             FROM\n                                               (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                       ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target\n                                                                                                                                                                                                                                                                                                                            ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2\n                                                FROM\n                                                  (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2\n                                                   FROM events AS e\n                                                   LEFT OUTER JOIN\n                                                     (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id\n                                                      FROM person_distinct_id_overrides\n                                                      WHERE equals(person_distinct_id_overrides.team_id, 99999)\n                                                      GROUP BY person_distinct_id_overrides.distinct_id\n                                                      HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id)\n                                                   WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))))))\n                                             WHERE ifNull(equals(step_0, 1), 0)))\n                                       GROUP BY aggregation_target, steps\n                                       HAVING ifNull(equals(steps, max(max_steps)), isNull(steps)\n                                                     and isNull(max(max_steps)))) AS step_runs\n                                    WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), 0), 1)) AS numbers) AS fill ON equals(results.bin_from_seconds, fill.bin_from_seconds)\n  ORDER BY fill.bin_from_seconds ASC\n  LIMIT 100 SETTINGS readonly=2,\n                     max_execution_time=60,\n                     allow_experimental_object_type=1,\n                     format_csv_allow_double_quotes=0,\n                     max_ast_elements=4000000,\n                     max_expanded_ast_elements=4000000,\n                     max_bytes_before_external_group_by=23622320128,\n                     allow_experimental_analyzer=1"
  },
  {
    "path": "parser/testdata/ddl/alter_role.sql",
    "content": "-- Tags: no-parallel\n\nALTER ROLE r1_01293;\nALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;\nALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;\nALTER ROLE r1_01293 SETTINGS NONE;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nALTER ROLE r6_01293 SETTINGS max_memory_usage CONST;\nALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nALTER ROLE r1_01293, r2_01293;\nALTER ROLE r1_01293 SETTINGS readonly=1;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nALTER ROLE r5_01293 SETTINGS NONE;\nALTER ROLE r1_01293@'%';\nALTER ROLE r2_01293@'%.myhost.com';"
  },
  {
    "path": "parser/testdata/ddl/alter_table_add_column.sql",
    "content": "ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2;\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_add_index.sql",
    "content": "ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_add_projection.sql",
    "content": "ALTER TABLE visits_order\nADD PROJECTION  IF NOT EXISTS user_name_projection\n(SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id;\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_add_projection_group_by_only.sql",
    "content": "ALTER TABLE events\nADD PROJECTION IF NOT EXISTS hourly_stats\n(SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type);\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_attach_partition.sql",
    "content": "ALTER TABLE test ATTACH PARTITION '20210114';\nALTER TABLE test ATTACH PARTITION '20210114' FROM test1;\nALTER TABLE test ATTACH PARTITION ID '20210114';\n\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_clear_column.sql",
    "content": "ALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_clear_index.sql",
    "content": "ALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_clear_projection.sql",
    "content": "ALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_delete.sql",
    "content": "ALTER TABLE test.events DELETE WHERE created_at < '2023-01-01';\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_delete_with_cluster.sql",
    "content": "ALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted';\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_detach_partition.sql",
    "content": "ALTER TABLE db.test DETACH PARTITION '2021-10-01';"
  },
  {
    "path": "parser/testdata/ddl/alter_table_drop_column.sql",
    "content": "ALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_drop_detach_partition.sql",
    "content": "ALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached = 1;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_drop_index.sql",
    "content": "ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_drop_partition.sql",
    "content": "ALTER TABLE test.events ON CLUSTER 'default_cluster' drop partition '2023-07-18';"
  },
  {
    "path": "parser/testdata/ddl/alter_table_drop_projection.sql",
    "content": "ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_freeze_no_specify_partition.sql",
    "content": "ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_freeze_partition.sql",
    "content": "ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze partition '2023-07-18';;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_materialize_index.sql",
    "content": "ALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403';\n\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_materialize_projection.sql",
    "content": "ALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403';\n\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_modify_column.sql",
    "content": "ALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test';"
  },
  {
    "path": "parser/testdata/ddl/alter_table_modify_column_remove.sql",
    "content": "ALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_modify_setting.sql",
    "content": "ALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_remove_ttl.sql",
    "content": "ALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_rename_column.sql",
    "content": "ALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name;\n\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_replace_partition.sql",
    "content": "ALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_reset_multiple_settings.sql",
    "content": "ALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_reset_setting.sql",
    "content": "ALTER TABLE example_table RESET SETTING max_part_loading_threads;"
  },
  {
    "path": "parser/testdata/ddl/alter_table_update.sql",
    "content": "ALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending';\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_update_in_partition.sql",
    "content": "ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';\n"
  },
  {
    "path": "parser/testdata/ddl/alter_table_update_with_cluster.sql",
    "content": "ALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100;\n"
  },
  {
    "path": "parser/testdata/ddl/attach_table_basic.sql",
    "content": "ATTACH TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);"
  },
  {
    "path": "parser/testdata/ddl/bug_001.sql",
    "content": "CREATE MATERIALIZED VIEW IF NOT EXISTS db.table\n            ON CLUSTER 'default_cluster' TO db.table_mv\nAS\nSELECT\n    event_ts,\n    org_id,\n    visitParamExtractString(properties, 'x') AS x,\n    visitParamExtractString(properties, 'y') AS y,\n    visitParamExtractString(properties, 'z') AS z,\n    visitParamExtractString(properties, 'a') AS a,\n    visitParamExtractString(properties, 'b') AS b,\n    visitParamExtractString(properties, 'c') AS c,\n    visitParamExtractString(properties, 'd') AS d,\n    visitParamExtractInt(properties, 'e') AS e,\n    visitParamExtractInt(properties, 'f') AS f\nFROM db.table\nWHERE db.table.event = 'hello';"
  },
  {
    "path": "parser/testdata/ddl/check.sql",
    "content": "CHECK TABLE test_table;\nCHECK TABLE test_table PARTITION 'col';\n"
  },
  {
    "path": "parser/testdata/ddl/create_database.sql",
    "content": "CREATE DATABASE IF NOT EXISTS `test`"
  },
  {
    "path": "parser/testdata/ddl/create_database_replicated.sql",
    "content": "CREATE DATABASE IF NOT EXISTS `test` ENGINE=Replicated('/root/test_local', 'shard', 'replica');\n"
  },
  {
    "path": "parser/testdata/ddl/create_dictionary_basic.sql",
    "content": "CREATE DICTIONARY test.my_dict (\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'default'\n    password ''\n    db 'test'\n    table 'dict_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192);"
  },
  {
    "path": "parser/testdata/ddl/create_dictionary_comprehensive.sql",
    "content": "CREATE OR REPLACE DICTIONARY test.comprehensive_dict \nUUID '12345678-1234-1234-1234-123456789012'\nON CLUSTER production_cluster\n(\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'root'\n    password 'secret'\n    db 'test_db'\n    table 'dictionary_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192, max_insert_block_size = 1048576);"
  },
  {
    "path": "parser/testdata/ddl/create_dictionary_with_comment.sql",
    "content": "CREATE DICTIONARY test.my_dict (\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'default'\n    password ''\n    db 'test'\n    table 'dict_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192)\nCOMMENT 'This is a test dictionary with comment';\n"
  },
  {
    "path": "parser/testdata/ddl/create_distributed_table.sql",
    "content": "create table test.event_all\nON CLUSTER 'default_cluster'\nAS test.evnets_local\nENGINE = Distributed(\n    default_cluster,\n    test,\n    events_local,\n    rand()\n) SETTINGS fsync_after_insert=0;\n"
  },
  {
    "path": "parser/testdata/ddl/create_function_simple.sql",
    "content": "CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b;"
  },
  {
    "path": "parser/testdata/ddl/create_live_view_basic.sql",
    "content": "CREATE LIVE VIEW my_live_view\nWITH TIMEOUT 10 TO my_destination(id String)\nAS SELECT id FROM my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/create_materialized_view_basic.sql",
    "content": "CREATE\nMATERIALIZED VIEW infra_bm.view_name \n    ON CLUSTER 'default_cluster' TO infra_bm.table_name\n(\n  `f1` DateTime64(3), \n  `f2` String, \n  `f3` String, \n  `f4` String, \n  `f5` String, \n  `f6` Int64\n) AS\nSELECT f1,\n       f2,\n       visitParamExtractString(properties, 'f3')   AS f3,\n       visitParamExtractString(properties, 'f4')      AS f4,\n       visitParamExtractString(properties, 'f5')    AS f5,\n    visitParamExtractInt(properties, 'f6') AS f6\nFROM\n    infra_bm.table_name1\nWHERE\n    infra_bm.table_name1.event = 'test-event'\nCOMMENT 'Comment for table';"
  },
  {
    "path": "parser/testdata/ddl/create_materialized_view_with_comment_before_as.sql",
    "content": "CREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table\n(\n    `shop_id` UInt64,\n    `event_type` LowCardinality(String),\n    `created_at` DateTime64(9)\n)\nCOMMENT '{\"blueprint_hash\":\"abc123\",\"timestamp\":\"2026-04-08T12:00:00Z\"}'\nAS SELECT\n    shop_id,\n    event_type,\n    created_at\nFROM db.src_table;\n"
  },
  {
    "path": "parser/testdata/ddl/create_materialized_view_with_definer.sql",
    "content": "CREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export\n(\n    `timestamp` DateTime64(9),\n    `field_1` String,\n    `field_2` String,\n)\nDEFINER = default SQL SECURITY DEFINER\nAS (SELECT\n    timestamp,\n    field_1,\n    field_2,\nFROM event_table\nWHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1)))\nCOMMENT 'Test comment'\n"
  },
  {
    "path": "parser/testdata/ddl/create_materialized_view_with_empty_table_schema.sql",
    "content": "CREATE MATERIALIZED VIEW test.t0 on cluster default_cluster\nENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}')\nPARTITION BY toYYYYMM(f0)\nORDER BY (f0)\nPOPULATE AS\nselect f0,f1,f2,coalesce(f0,f1) as f333\nfrom\n    (select\n         f0,f1,f2,\n         ROW_NUMBER() over(partition by f0 order by coalesce(f1,f2)) as rn\n     from test.t\n     where f3 in ('foo', 'bar', 'test')\n       and env ='test'\n    ) as tmp\nwhere rn = 1;"
  },
  {
    "path": "parser/testdata/ddl/create_materialized_view_with_gcs.sql",
    "content": "CREATE MATERIALIZED VIEW database_name.view_name\n        REFRESH EVERY 5 MINUTE TO database_name.table_name AS\n        SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/');"
  },
  {
    "path": "parser/testdata/ddl/create_materialized_view_with_refresh.sql",
    "content": "CREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE\nRANDOMIZE FOR 1 SECOND\nDEPENDS ON  table_v5\nSETTINGS\n    randomize_for = 1,\n    randomize_offset = 10,\n    randomize_period = 1\nAPPEND TO target_table_name\nEMPTY\nAS SELECT\n    `field_1`,\n    `field_2`,\n    `field_3`,\nFROM table_v5"
  },
  {
    "path": "parser/testdata/ddl/create_mv_with_not_op.sql",
    "content": "CREATE MATERIALIZED VIEW infra_bm.view_name\n    ON CLUSTER 'default_cluster' TO infra_bm.table_name\n(\n  `f1` DateTime64(3),\n  `f2` String,\n  `f3` String,\n  `f4` String,\n  `f5` String,\n  `f6` Int64\n) AS\nSELECT f1,\n       f2,\n       visitParamExtractString(properties, 'f3') AS f3,\n       visitParamExtractString(properties, 'f4') AS f4,\n       visitParamExtractString(properties, 'f5') AS f5,\n       visitParamExtractInt(properties, 'f6') AS f6\nFROM infra_bm.table_name1\nWHERE infra_bm.table_name1.event = 'test-event' AND\n    NOT isZeroOrNull(f2) AND f6-2 > 0"
  },
  {
    "path": "parser/testdata/ddl/create_mv_with_order_by.sql",
    "content": "CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nORDER BY (id)\nAS\nSELECT * FROM test_table;\n\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nAS\nSELECT * FROM test_table;"
  },
  {
    "path": "parser/testdata/ddl/create_named_collection_basic.sql",
    "content": "CREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config\nAS url = 'http://local-minio:9000/*',\naccess_key_id = 'minioadmin',\nsecret_access_key = 'minioadmin';\n"
  },
  {
    "path": "parser/testdata/ddl/create_named_collection_simple.sql",
    "content": "CREATE NAMED COLLECTION my_collection\nAS key1 = 'value1',\nkey2 = 'value2';\n"
  },
  {
    "path": "parser/testdata/ddl/create_named_collection_with_cluster.sql",
    "content": "CREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster\nAS key1 = 'value1' OVERRIDABLE,\nkey2 = 'value2' NOT OVERRIDABLE,\nkey3 = 'value3';\n"
  },
  {
    "path": "parser/testdata/ddl/create_named_collection_with_overridable.sql",
    "content": "CREATE NAMED COLLECTION test_collection\nAS url = 'http://example.com' OVERRIDABLE,\naccess_key = 'key123' NOT OVERRIDABLE,\nsecret_key = 'secret456';\n"
  },
  {
    "path": "parser/testdata/ddl/create_or_replace.sql",
    "content": "-- It's a short link events table\n/**\n    * @name Short link events\n    * @description It's a short link events table\n */\nCREATE OR REPLACE TABLE IF NOT EXISTS test.events_local (\n    f0 String,\n    f1 String CODEC(ZSTD(1)),\n    f2 VARCHAR(255),\n) ENGINE = MergeTree\nPRIMARY KEY (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f1)\nTTL f1 + INTERVAL 6 MONTH\nORDER BY (f1,f2)\nCOMMENT 'Comment for table';\n\nCREATE OR REPLACE VIEW IF NOT EXISTS my_view(col1 String, col2 String)\nAS\nSELECT\n    id,\n    name\nFROM\n    my_table;\n\nCREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y;"
  },
  {
    "path": "parser/testdata/ddl/create_role.sql",
    "content": "-- Tags: no-parallel\n\nCREATE ROLE r1_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2;\nCREATE ROLE r1_01293 SETTINGS NONE;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nCREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nCREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nCREATE ROLE r6_01293 SETTINGS max_memory_usage CONST;\nCREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nCREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nCREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 SETTINGS readonly=1;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nCREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nCREATE ROLE r5_01293 SETTINGS NONE;\nCREATE ROLE r1_01293@'%';\nCREATE ROLE r2_01293@'%.myhost.com';"
  },
  {
    "path": "parser/testdata/ddl/create_table_as_remote_function.sql",
    "content": "-- CREATE TABLE with columns AS table function (remoteSecure)\nCREATE TABLE test_remote\n(\n    id UInt64,\n    name String,\n    value Int32\n)\nAS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password');\n\n-- Simpler test case with remote()\nCREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table');\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_basic.sql",
    "content": "-- It's a short link events table\n/**\n    * @name Short link events\n    * @description It's a short link events table\n */\nCREATE TABLE IF NOT EXISTS test.events_local (\n    f0 String,\n    f1 String CODEC(ZSTD(1)),\n    f2 VARCHAR(255),\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Nested (\n        f70 UInt32,\n        f71 UInt32,\n        f72 DateTime,\n        f73 Int64,\n        f74 Int64,\n        f75 String\n    ),\n    f8 Datetime DEFAULT now(),\n    f9 String MATERIALIZED toString(f7['f70']),\n    f10 String ALIAS f11,\n    f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello'),\n) ENGINE = MergeTree\nPRIMARY KEY (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f3)\nTTL f3 + INTERVAL 6 MONTH\nORDER BY (f1,f2,f3)\nCOMMENT 'Comment for table';"
  },
  {
    "path": "parser/testdata/ddl/create_table_codec_no_args.sql",
    "content": "CREATE TABLE shark_attacks (\n    timestamp DateTime CODEC(DoubleDelta),\n);"
  },
  {
    "path": "parser/testdata/ddl/create_table_json_typehints.sql",
    "content": "CREATE TABLE t (\n    j JSON(message String, a.b UInt64, max_dynamic_paths=0, SKIP x, SKIP REGEXP 're')\n) ENGINE = MergeTree\nORDER BY tuple();\n\n\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_codec_delta.sql",
    "content": "CREATE TABLE IF NOT EXISTS test_local\n(\n `id` UInt64 CODEC(Delta, ZSTD(1)),\n `api_id` UInt64 CODEC(ZSTD(1)),\n `app_id` UInt64 CODEC(Delta(9), ZSTD(1)),\n `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)),\n `guage` Float64 CODEC(Gorilla, LZ4),\n `value` UInt64 CODEC(T64, LZ4),\n `timestamp` DateTime64(9) CODEC(ZSTD(1)),\n INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nPARTITION BY toStartOfHour(`timestamp`)\nORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_enum_fields.sql",
    "content": "CREATE TABLE t0 on cluster default_cluster\n(\n    `method` Enum8('GET'=1 , 'POST'=2, 'HEAD'=3, 'PUT'=4,'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)),\n    `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD)\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nPARTITION BY toDate(timestamp)\nORDER BY (method,timestamp)\nTTL toDate(timestamp) + toIntervalDay(3)\nSETTINGS index_granularity = 8192;"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_index.sql",
    "content": "CREATE TABLE IF NOT EXISTS test_local\n(\n `common.id` String CODEC(ZSTD(1)),\n `id` UInt64 CODEC(Delta, ZSTD(1)),\n `idx` UInt64 CODEC(Delta, ZSTD(1)),\n `api_id` UInt64 CODEC(ZSTD(1)),\n `arr` Array(Int64),\n `content` String CODEC(ZSTD(1)),\n `output` String,\n INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1,\n INDEX id_idx id TYPE minmax GRANULARITY 10,\n INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1,\n INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2,\n INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3,\n INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1,\n INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nPARTITION BY toStartOfHour(`timestamp`)\nORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_keyword_partition_by.sql",
    "content": "CREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' (\n    `date` Date,\n    `f1` String,\n    `f2` String,\n    `f3` UInt64\n    ) ENGINE = ReplacingMergeTree\n    PARTITION BY date\n    ORDER BY (f1, f2)\n    SETTINGS index_granularity = 8192;"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_null_engine.sql",
    "content": "CREATE TABLE logs.t0 on cluster default\n(\n    `trace_id` String CODEC(ZSTD(1)),\n    INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64\n) ENGINE = Null();"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_nullable.sql",
    "content": "CREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5`\n    UUID '27673372-7973-44f5-a767-33727973c4f5' (\n    `f0` String,\n    `f1` String,\n    `f2` LowCardinality(String),\n    `f3` LowCardinality(String),\n    `f4` DateTime64(3),\n    `f5` Nullable(DateTime64(3)),\n    `succeed_at` Nullable(DateTime64(3))\n) ENGINE = MergeTree\nPARTITION BY xxHash32(tag_id) % 20\nORDER BY label_id\nSETTINGS index_granularity = 8192;\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_on_clsuter.sql",
    "content": "CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_projection.sql",
    "content": "CREATE TABLE events\n(\n    `event_time` DateTime,\n    `event_id` UInt64,\n    `user_id` UInt64,\n    `huge_string` String,\n    PROJECTION order_by_user_id\n    (\n        SELECT\n            _part_offset\n        ORDER BY user_id\n    )\n)\nENGINE = MergeTree()\nORDER BY (event_id); "
  },
  {
    "path": "parser/testdata/ddl/create_table_with_projection_group_by_only.sql",
    "content": "CREATE TABLE events\n(\n    `event_time` DateTime,\n    `event_type` String,\n    `user_id` UInt64,\n    `value` Float64,\n    PROJECTION hourly_aggregates\n    (\n        SELECT\n            toStartOfHour(event_time) AS hour,\n            event_type,\n            count() AS event_count,\n            sum(value) AS total_value\n        GROUP BY hour, event_type\n    )\n)\nENGINE = MergeTree()\nORDER BY (event_time, event_type);\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_qbit.sql",
    "content": "CREATE TABLE test.qbit_example (\n    id UInt32,\n    vec QBit(Float32, 8)\n) ENGINE = Memory;\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_sample_by.sql",
    "content": "CREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e'\n(\n    `f0` DateTime,\n    `f1` UInt32,\n    `f3` UInt32\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}')\nPARTITION BY toYYYYMM(timestamp)\nORDER BY (contractid, toDate(timestamp), userid)\nSAMPLE BY userid\nSETTINGS index_granularity = 8192;"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_ttl_policy.sql",
    "content": "CREATE TABLE tab\n(\n    d DateTime,\n    a Int\n)\n    ENGINE = MergeTree\nPARTITION BY toYYYYMM(d)\nORDER BY d\nTTL d + INTERVAL 1 MONTH DELETE,\n    d + INTERVAL 1 WEEK TO VOLUME 'aaa',\n    d + INTERVAL 2 WEEK TO DISK 'bbb';\n\n\nCREATE TABLE table_with_where\n(\n    d DateTime,\n    a Int\n)\n    ENGINE = MergeTree\nPARTITION BY toYYYYMM(d)\nORDER BY d\nTTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1;\n\nCREATE TABLE table_for_recompression\n(\n    d DateTime,\n    key UInt64,\n    value String\n) ENGINE MergeTree()\nORDER BY tuple()\nPARTITION BY key\nTTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10))\nSETTINGS min_rows_for_wide_part = 0, min_bytes_for_wide_part = 0, allow_experimental_replacing_merge_with_cleanup = true;\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_tuple_fields.sql",
    "content": "CREATE TABLE t0 on cluster default_cluster\n(\n    `tup0` Tuple(),\n    `tup1` Tuple(String, Int64),\n    `tup2` Tuple(String, Tuple(String, String)),\n    `tup3` Tuple(a String, cd Tuple(c String, d String))\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nORDER BY (tup1, tup2, tup3)\nSETTINGS index_granularity = 8192;\n"
  },
  {
    "path": "parser/testdata/ddl/create_table_with_uuid.sql",
    "content": "CREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);"
  },
  {
    "path": "parser/testdata/ddl/create_user.sql",
    "content": "-- Basic CREATE USER tests\n\nCREATE USER user1;\nCREATE USER IF NOT EXISTS user2;\nCREATE USER OR REPLACE user3;\nCREATE USER user4, user5;\n\n-- CREATE USER with authentication\nCREATE USER user6 NOT IDENTIFIED;\nCREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123';\nCREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123';\nCREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server';\nCREATE USER user10 IDENTIFIED WITH kerberos;\nCREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM';\n\n-- CREATE USER with VALID UNTIL\nCREATE USER user33 VALID UNTIL '2026-12-12 00:00:00';\nCREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15';\nCREATE USER user35 VALID UNTIL 'infinity';\n\n-- CREATE USER with host restrictions\nCREATE USER user12 HOST LOCAL;\nCREATE USER user13 HOST ANY;\nCREATE USER user14 HOST NONE;\nCREATE USER user15 HOST NAME 'localhost';\nCREATE USER user16 HOST REGEXP '.*\\.example\\.com';\nCREATE USER user17 HOST IP '192.168.1.1';\nCREATE USER user18 HOST LIKE 'test%';\n\n-- CREATE USER with default roles\nCREATE USER user19 DEFAULT ROLE role1;\nCREATE USER user20 DEFAULT ROLE role1, role2;\nCREATE USER user21 DEFAULT ROLE NONE;\n\n-- CREATE USER with default database\nCREATE USER user22 DEFAULT DATABASE test_db;\nCREATE USER user23 DEFAULT DATABASE NONE;\n\n-- CREATE USER with grantees\nCREATE USER user24 GRANTEES user1;\nCREATE USER user25 GRANTEES user1, user2;\nCREATE USER user26 GRANTEES ANY;\nCREATE USER user27 GRANTEES NONE;\nCREATE USER user28 GRANTEES user1, user2 EXCEPT user3;\n\n-- CREATE USER with settings\nCREATE USER user29 SETTINGS max_memory_usage=5000000;\nCREATE USER user30 SETTINGS PROFILE 'default';\nCREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000;\n\n-- Complex CREATE USER with multiple clauses\nCREATE USER user32\n    IDENTIFIED WITH plaintext_password BY 'password'\n    VALID UNTIL '2025-12-31'\n    HOST NAME 'localhost'\n    DEFAULT ROLE role1, role2\n    DEFAULT DATABASE test_db\n    GRANTEES user1, user2 EXCEPT user3\n    SETTINGS max_memory_usage=5000000, readonly=1;"
  },
  {
    "path": "parser/testdata/ddl/create_view_basic.sql",
    "content": "CREATE VIEW IF NOT EXISTS my_view(col1 String, col2 String)\nAS\nSELECT\n    id,\n    name\nFROM\n    my_table;"
  },
  {
    "path": "parser/testdata/ddl/create_view_on_cluster_with_uuid.sql",
    "content": "CREATE VIEW IF NOT EXISTS cluster_name.my_view\n        UUID '3493e374-e2bb-481b-b493-e374e2bb981b'\n        ON CLUSTER 'my_cluster'\nAS (\n    SELECT\n    column1,\n    column2\n    FROM\n    my_other_table\n);"
  },
  {
    "path": "parser/testdata/ddl/create_view_with_comment.sql",
    "content": "CREATE VIEW IF NOT EXISTS db.my_view\n(\n    `id` Int64,\n    `name` String\n)\nCOMMENT '{\"blueprint_hash\":\"abc123\"}'\nAS SELECT\n    id,\n    name\nFROM db.my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/create_with_time_zone.sql",
    "content": "CREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster\n(\n    `f0` Array(Tuple(\n        f00 DateTime64(9, 'UTC'),\n        f01 String,\n        f02 Map(String, String),\n        f03 Map(String, Float64),\n        f04 Map(String, BOOL))) CODEC(ZSTD(1)\n    ),\n    `f1` UInt64 CODEC(Delta(8), LZ4),\n    `f2` FixedString(16) CODEC(LZ4),\n    `f3` FixedString(8) CODEC(LZ4),\n    `f4` FixedString(8) CODEC(LZ4),\n    `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4),\n    `f6` UInt64 CODEC(Delta(8), LZ4),\n    `f7` LowCardinality(String) CODEC(ZSTD(1)),\n    `f8` String CODEC(ZSTD(1)),\n    `f9` LowCardinality(String) CODEC(ZSTD(1)),\n    `f10` String CODEC(ZSTD(1)),\n    `f11` LowCardinality(String) CODEC(ZSTD(1)),\n    `f12` LowCardinality(String) CODEC(ZSTD(1)),\n    `f13` String CODEC(ZSTD(1)),\n    `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n    `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n    `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)),\n    `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)),\n    `f18` Array(Tuple(\n        f180 FixedString(16),\n        f181 FixedString(8),\n        f182 String,\n        f183 Map(String, String))) CODEC(ZSTD(1)),\n        `f184` String CODEC(ZSTD(1)),\n        `f185` String CODEC(ZSTD(1)),\n        `f186` String CODEC(ZSTD(1)),\n        `f187` UInt32 CODEC(ZSTD(1)),\n        `f188` DATETIME DEFAULT now(),\n        INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1,\n        INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1,\n        INDEX idx_f2 f2 TYPE minmax GRANULARITY 1,\n        INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4,\n        INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1,\n        INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4\n    )\n    ENGINE = MergeTree\n    PARTITION BY toDate(timestamp)\n    ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp))\n    TTL toDate(timestamp) + toIntervalDay(15)\n    SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1"
  },
  {
    "path": "parser/testdata/ddl/desc_table_with_table_keyword.sql",
    "content": "DESC TABLE mytable"
  },
  {
    "path": "parser/testdata/ddl/desc_table_without_table_keyword.sql",
    "content": "DESC mytable"
  },
  {
    "path": "parser/testdata/ddl/describe_table_with_table_keyword.sql",
    "content": "DESCRIBE TABLE mytable"
  },
  {
    "path": "parser/testdata/ddl/describe_table_without_table_keyword.sql",
    "content": "DESCRIBE mytable"
  },
  {
    "path": "parser/testdata/ddl/drop_database.sql",
    "content": "DROP DATABASE IF EXISTS datbase_name;\n"
  },
  {
    "path": "parser/testdata/ddl/drop_role.sql",
    "content": "DROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293;\nDROP ROLE IF EXISTS r2_01293_renamed;\nDROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/drop_table_basic.sql",
    "content": "DROP TABLE IF EXISTS test.table_name;\n"
  },
  {
    "path": "parser/testdata/ddl/drop_table_with_no_delay.sql",
    "content": "DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY;\n"
  },
  {
    "path": "parser/testdata/ddl/drop_table_with_on_clsuter.sql",
    "content": "DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_role.sql",
    "content": "-- Origin SQL:\n-- Tags: no-parallel\n\nALTER ROLE r1_01293;\nALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;\nALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;\nALTER ROLE r1_01293 SETTINGS NONE;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nALTER ROLE r6_01293 SETTINGS max_memory_usage CONST;\nALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nALTER ROLE r1_01293, r2_01293;\nALTER ROLE r1_01293 SETTINGS readonly=1;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nALTER ROLE r5_01293 SETTINGS NONE;\nALTER ROLE r1_01293@'%';\nALTER ROLE r2_01293@'%.myhost.com';\n\n-- Format SQL:\nALTER ROLE r1_01293;\nALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;\nALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;\nALTER ROLE r1_01293 SETTINGS NONE;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nALTER ROLE r6_01293 SETTINGS max_memory_usage CONST;\nALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nALTER ROLE r1_01293, r2_01293;\nALTER ROLE r1_01293 SETTINGS readonly=1;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nALTER ROLE r5_01293 SETTINGS NONE;\nALTER ROLE r1_01293@'%';\nALTER ROLE r2_01293@'%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_add_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2;\n\n\n-- Format SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync=2;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_add_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;\n\n\n-- Format SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_add_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE visits_order\nADD PROJECTION  IF NOT EXISTS user_name_projection\n(SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id;\n\n\n-- Format SQL:\nALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_add_projection_group_by_only.sql",
    "content": "-- Origin SQL:\nALTER TABLE events\nADD PROJECTION IF NOT EXISTS hourly_stats\n(SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type);\n\n\n-- Format SQL:\nALTER TABLE events ADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type);\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_attach_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test ATTACH PARTITION '20210114';\nALTER TABLE test ATTACH PARTITION '20210114' FROM test1;\nALTER TABLE test ATTACH PARTITION ID '20210114';\n\n\n\n-- Format SQL:\nALTER TABLE test ATTACH PARTITION '20210114';\nALTER TABLE test ATTACH PARTITION '20210114' FROM test1;\nALTER TABLE test ATTACH PARTITION '20210114';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_clear_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name;\n\n-- Format SQL:\nALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_clear_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name;\n\n-- Format SQL:\nALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_clear_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name;\n\n-- Format SQL:\nALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_delete.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events DELETE WHERE created_at < '2023-01-01';\n\n\n-- Format SQL:\nALTER TABLE test.events DELETE WHERE created_at < '2023-01-01';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_delete_with_cluster.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted';\n\n\n-- Format SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_detach_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE db.test DETACH PARTITION '2021-10-01';\n\n-- Format SQL:\nALTER TABLE db.test DETACH PARTITION '2021-10-01';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_drop_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1;\n\n-- Format SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_drop_detach_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached = 1;\n\n-- Format SQL:\nALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_drop_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1;\n\n-- Format SQL:\nALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_drop_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' drop partition '2023-07-18';\n\n-- Format SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' DROP PARTITION '2023-07-18';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_drop_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1;\n\n-- Format SQL:\nALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_freeze_no_specify_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' freeze;\n\n-- Format SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' FREEZE;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_freeze_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' freeze partition '2023-07-18';;\n\n-- Format SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' FREEZE PARTITION '2023-07-18';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_materialize_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403';\n\n\n\n-- Format SQL:\nALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_materialize_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403';\n\n\n\n-- Format SQL:\nALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_modify_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test';\n\n-- Format SQL:\nALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_modify_column_remove.sql",
    "content": "-- Origin SQL:\nALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT;\n\n-- Format SQL:\nALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_modify_setting.sql",
    "content": "-- Origin SQL:\nALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000;\n\n-- Format SQL:\nALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_remove_ttl.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL;\n\n-- Format SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_rename_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name;\n\n\n\n-- Format SQL:\nALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_replace_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1;\n\n-- Format SQL:\nALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_reset_multiple_settings.sql",
    "content": "-- Origin SQL:\nALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting;\n\n-- Format SQL:\nALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_reset_setting.sql",
    "content": "-- Origin SQL:\nALTER TABLE example_table RESET SETTING max_part_loading_threads;\n\n-- Format SQL:\nALTER TABLE example_table RESET SETTING max_part_loading_threads;\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_update.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending';\n\n\n-- Format SQL:\nALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_update_in_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';\n\n\n-- Format SQL:\nALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';\n"
  },
  {
    "path": "parser/testdata/ddl/format/alter_table_update_with_cluster.sql",
    "content": "-- Origin SQL:\nALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100;\n\n\n-- Format SQL:\nALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100;\n"
  },
  {
    "path": "parser/testdata/ddl/format/attach_table_basic.sql",
    "content": "-- Origin SQL:\nATTACH TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now()) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_role.sql",
    "content": "-- Origin SQL:\n-- Tags: no-parallel\n\nALTER ROLE r1_01293;\nALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;\nALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;\nALTER ROLE r1_01293 SETTINGS NONE;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nALTER ROLE r6_01293 SETTINGS max_memory_usage CONST;\nALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nALTER ROLE r1_01293, r2_01293;\nALTER ROLE r1_01293 SETTINGS readonly=1;\nALTER ROLE r2_01293 SETTINGS PROFILE 'default';\nALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nALTER ROLE r5_01293 SETTINGS NONE;\nALTER ROLE r1_01293@'%';\nALTER ROLE r2_01293@'%.myhost.com';\n\n-- Beautify SQL:\nALTER ROLE r1_01293;\nALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;\nALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;\nALTER ROLE r1_01293\nSETTINGS\n  NONE;\nALTER ROLE r2_01293\nSETTINGS\n  PROFILE 'default';\nALTER ROLE r3_01293\nSETTINGS\n  max_memory_usage=5000000;\nALTER ROLE r4_01293\nSETTINGS\n  max_memory_usage\n  MIN=5000000;\nALTER ROLE r5_01293\nSETTINGS\n  max_memory_usage\n  MAX=5000000;\nALTER ROLE r6_01293\nSETTINGS\n  max_memory_usage\n  CONST;\nALTER ROLE r7_01293\nSETTINGS\n  max_memory_usage\n  WRITABLE;\nALTER ROLE r8_01293\nSETTINGS\n  max_memory_usage=5000000\n  MIN 4000000\n  MAX 6000000\n  CONST;\nALTER ROLE r9_01293\nSETTINGS\n  PROFILE 'default',\n  max_memory_usage=5000000\n  WRITABLE;\nALTER ROLE r1_01293, r2_01293;\nALTER ROLE r1_01293\nSETTINGS\n  readonly=1;\nALTER ROLE r2_01293\nSETTINGS\n  PROFILE 'default';\nALTER ROLE r3_01293\nSETTINGS\n  max_memory_usage=5000000\n  MIN 4000000\n  MAX 6000000\n  WRITABLE;\nALTER ROLE r4_01293\nSETTINGS\n  PROFILE 'default',\n  max_memory_usage=5000000,\n  readonly=1;\nALTER ROLE r5_01293\nSETTINGS\n  NONE;\nALTER ROLE r1_01293@'%';\nALTER ROLE r2_01293@'%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_add_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2;\n\n\n-- Beautify SQL:\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD COLUMN f1 String AFTER f0\nSETTINGS\n  alter_sync=2;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_add_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;\n\n\n-- Beautify SQL:\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_add_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE visits_order\nADD PROJECTION  IF NOT EXISTS user_name_projection\n(SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id;\n\n\n-- Beautify SQL:\nALTER TABLE visits_order\nADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY\n  user_name ORDER BY user_name) AFTER a.user_id;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_add_projection_group_by_only.sql",
    "content": "-- Origin SQL:\nALTER TABLE events\nADD PROJECTION IF NOT EXISTS hourly_stats\n(SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type);\n\n\n-- Beautify SQL:\nALTER TABLE events\nADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY\n  hour, event_type);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_attach_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test ATTACH PARTITION '20210114';\nALTER TABLE test ATTACH PARTITION '20210114' FROM test1;\nALTER TABLE test ATTACH PARTITION ID '20210114';\n\n\n\n-- Beautify SQL:\nALTER TABLE test\nATTACH PARTITION '20210114';\nALTER TABLE test\nATTACH PARTITION '20210114' FROM test1;\nALTER TABLE test\nATTACH PARTITION '20210114';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_clear_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name;\n\n-- Beautify SQL:\nALTER TABLE my_table\nCLEAR COLUMN my_column_name\nIN PARTITION partition_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_clear_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name;\n\n-- Beautify SQL:\nALTER TABLE my_table\nCLEAR INDEX my_index_name\nIN PARTITION partition_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_clear_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name;\n\n-- Beautify SQL:\nALTER TABLE my_table\nCLEAR PROJECTION hello\nIN PARTITION partition_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_delete.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events DELETE WHERE created_at < '2023-01-01';\n\n\n-- Beautify SQL:\nALTER TABLE test.events\nDELETE\nWHERE created_at < '2023-01-01';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_delete_with_cluster.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted';\n\n\n-- Beautify SQL:\nALTER TABLE test.events\nON CLUSTER 'default_cluster'\nDELETE\nWHERE id = 123\nAND\n  status = 'deleted';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_detach_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE db.test DETACH PARTITION '2021-10-01';\n\n-- Beautify SQL:\nALTER TABLE db.test\nDETACH PARTITION '2021-10-01';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_drop_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1;\n\n-- Beautify SQL:\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nDROP COLUMN IF EXISTS f1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_drop_detach_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached = 1;\n\n-- Beautify SQL:\nALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local\nDROP DETACHED PARTITION '2022-05-24'\nSETTINGS\n  allow_drop_detached=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_drop_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1;\n\n-- Beautify SQL:\nALTER TABLE test.event_local\nON CLUSTER 'default_cluster'\nDROP INDEX f1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_drop_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' drop partition '2023-07-18';\n\n-- Beautify SQL:\nALTER TABLE test.events\nON CLUSTER 'default_cluster'\nDROP PARTITION '2023-07-18';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_drop_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1;\n\n-- Beautify SQL:\nALTER TABLE test.event_local\nON CLUSTER 'default_cluster'\nDROP PROJECTION f1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_freeze_no_specify_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' freeze;\n\n-- Beautify SQL:\nALTER TABLE test.events\nON CLUSTER 'default_cluster'\nFREEZE;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_freeze_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' freeze partition '2023-07-18';;\n\n-- Beautify SQL:\nALTER TABLE test.events\nON CLUSTER 'default_cluster'\nFREEZE PARTITION '2023-07-18';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_materialize_index.sql",
    "content": "-- Origin SQL:\nALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403';\n\n\n\n-- Beautify SQL:\nALTER TABLE visits_order\nMATERIALIZE INDEX IF EXISTS user_name_index\nIN PARTITION '20240403';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_materialize_projection.sql",
    "content": "-- Origin SQL:\nALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403';\n\n\n\n-- Beautify SQL:\nALTER TABLE visits_order\nMATERIALIZE PROJECTION IF EXISTS user_name_projection\nIN PARTITION '20240403';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_modify_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test';\n\n-- Beautify SQL:\nALTER TABLE t1\nMODIFY COLUMN f1 String COMMENT 'test';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_modify_column_remove.sql",
    "content": "-- Origin SQL:\nALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT;\n\n-- Beautify SQL:\nALTER TABLE t1\nMODIFY COLUMN f1 REMOVE COMMENT;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_modify_setting.sql",
    "content": "-- Origin SQL:\nALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000;\n\n-- Beautify SQL:\nALTER TABLE example_table\nMODIFY SETTING\n  max_part_loading_threads=8,\n  max_parts_in_total=50000;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_remove_ttl.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL;\n\n-- Beautify SQL:\nALTER TABLE test.events\nON CLUSTER 'default_cluster'\nREMOVE TTL;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_rename_column.sql",
    "content": "-- Origin SQL:\nALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name;\n\n\n\n-- Beautify SQL:\nALTER TABLE my_table\nRENAME COLUMN old_column_name TO new_column_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_replace_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1;\n\n-- Beautify SQL:\nALTER TABLE t2\nREPLACE PARTITION 'partition' FROM t1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_reset_multiple_settings.sql",
    "content": "-- Origin SQL:\nALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting;\n\n-- Beautify SQL:\nALTER TABLE example_table\nRESET SETTING\n  max_part_loading_threads,\n  max_parts_in_total,\n  another_setting;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_reset_setting.sql",
    "content": "-- Origin SQL:\nALTER TABLE example_table RESET SETTING max_part_loading_threads;\n\n-- Beautify SQL:\nALTER TABLE example_table\nRESET SETTING\n  max_part_loading_threads;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_update.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending';\n\n\n-- Beautify SQL:\nALTER TABLE test.users\nUPDATE\n  status = 'active',\n  updated_at = now()\nWHERE status = 'pending';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_update_in_partition.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';\n\n\n-- Beautify SQL:\nALTER TABLE test.users\nUPDATE\n  status = 'inactive'\nIN PARTITION '2024-01-01'\nWHERE status = 'active';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/alter_table_update_with_cluster.sql",
    "content": "-- Origin SQL:\nALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100;\n\n\n-- Beautify SQL:\nALTER TABLE db.table\nON CLUSTER cluster1\nUPDATE\n  column1 = column1 + 1\nWHERE id > 100;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/attach_table_basic.sql",
    "content": "-- Origin SQL:\nATTACH TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster'\n(\n  f0 String,\n  f1 String,\n  f2 String,\n  f3 Datetime,\n  f4 Datetime,\n  f5 Map(String, String),\n  f6 String,\n  f7 Datetime DEFAULT now()\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nORDER BY\n  (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f3)\nTTL f3 + INTERVAL 6 MONTH;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/bug_001.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS db.table\n            ON CLUSTER 'default_cluster' TO db.table_mv\nAS\nSELECT\n    event_ts,\n    org_id,\n    visitParamExtractString(properties, 'x') AS x,\n    visitParamExtractString(properties, 'y') AS y,\n    visitParamExtractString(properties, 'z') AS z,\n    visitParamExtractString(properties, 'a') AS a,\n    visitParamExtractString(properties, 'b') AS b,\n    visitParamExtractString(properties, 'c') AS c,\n    visitParamExtractString(properties, 'd') AS d,\n    visitParamExtractInt(properties, 'e') AS e,\n    visitParamExtractInt(properties, 'f') AS f\nFROM db.table\nWHERE db.table.event = 'hello';\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS db.table\nON CLUSTER 'default_cluster'\nTO db.table_mv\nAS\n  SELECT\n    event_ts,\n    org_id,\n    visitParamExtractString(properties, 'x') AS x,\n    visitParamExtractString(properties, 'y') AS y,\n    visitParamExtractString(properties, 'z') AS z,\n    visitParamExtractString(properties, 'a') AS a,\n    visitParamExtractString(properties, 'b') AS b,\n    visitParamExtractString(properties, 'c') AS c,\n    visitParamExtractString(properties, 'd') AS d,\n    visitParamExtractInt(properties, 'e') AS e,\n    visitParamExtractInt(properties, 'f') AS f\n  FROM\n    db.table\n  WHERE\n    db.table.event = 'hello';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/check.sql",
    "content": "-- Origin SQL:\nCHECK TABLE test_table;\nCHECK TABLE test_table PARTITION 'col';\n\n\n-- Beautify SQL:\nCHECK TABLE test_table;\nCHECK TABLE test_table PARTITION 'col';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_database.sql",
    "content": "-- Origin SQL:\nCREATE DATABASE IF NOT EXISTS `test`\n\n-- Beautify SQL:\nCREATE DATABASE IF NOT EXISTS `test`;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_database_replicated.sql",
    "content": "-- Origin SQL:\nCREATE DATABASE IF NOT EXISTS `test` ENGINE=Replicated('/root/test_local', 'shard', 'replica');\n\n\n-- Beautify SQL:\nCREATE DATABASE IF NOT EXISTS `test`\nENGINE = Replicated('/root/test_local', 'shard', 'replica');\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_dictionary_basic.sql",
    "content": "-- Origin SQL:\nCREATE DICTIONARY test.my_dict (\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'default'\n    password ''\n    db 'test'\n    table 'dict_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192);\n\n-- Beautify SQL:\nCREATE DICTIONARY test.my_dict\n(\n  id UInt64,\n  name String DEFAULT '',\n  value Float64 EXPRESSION toFloat64OrZero(name),\n  parent_id UInt64 HIERARCHICAL,\n  is_active UInt8 INJECTIVE,\n  object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table'))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size=8192);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_dictionary_comprehensive.sql",
    "content": "-- Origin SQL:\nCREATE OR REPLACE DICTIONARY test.comprehensive_dict \nUUID '12345678-1234-1234-1234-123456789012'\nON CLUSTER production_cluster\n(\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'root'\n    password 'secret'\n    db 'test_db'\n    table 'dictionary_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192, max_insert_block_size = 1048576);\n\n-- Beautify SQL:\nCREATE OR REPLACE DICTIONARY test.comprehensive_dict\nUUID '12345678-1234-1234-1234-123456789012'\nON CLUSTER production_cluster\n(\n  id UInt64,\n  name String DEFAULT '',\n  value Float64 EXPRESSION toFloat64OrZero(name),\n  parent_id UInt64 HIERARCHICAL,\n  is_active UInt8 INJECTIVE,\n  object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table'))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size=8192, max_insert_block_size=1048576);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_dictionary_with_comment.sql",
    "content": "-- Origin SQL:\nCREATE DICTIONARY test.my_dict (\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'default'\n    password ''\n    db 'test'\n    table 'dict_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192)\nCOMMENT 'This is a test dictionary with comment';\n\n\n-- Beautify SQL:\nCREATE DICTIONARY test.my_dict\n(\n  id UInt64,\n  name String DEFAULT '',\n  value Float64 EXPRESSION toFloat64OrZero(name),\n  parent_id UInt64 HIERARCHICAL,\n  is_active UInt8 INJECTIVE,\n  object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table'))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size=8192)\nCOMMENT 'This is a test dictionary with comment';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_distributed_table.sql",
    "content": "-- Origin SQL:\ncreate table test.event_all\nON CLUSTER 'default_cluster'\nAS test.evnets_local\nENGINE = Distributed(\n    default_cluster,\n    test,\n    events_local,\n    rand()\n) SETTINGS fsync_after_insert=0;\n\n\n-- Beautify SQL:\nCREATE TABLE test.event_all ON CLUSTER 'default_cluster'\n AS test.evnets_local\nENGINE = Distributed(default_cluster, test, events_local, rand())\nSETTINGS\n  fsync_after_insert=0;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_function_simple.sql",
    "content": "-- Origin SQL:\nCREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b;\n\n-- Beautify SQL:\nCREATE FUNCTION linear_equation AS (x, k, b) -> k * x + b;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_live_view_basic.sql",
    "content": "-- Origin SQL:\nCREATE LIVE VIEW my_live_view\nWITH TIMEOUT 10 TO my_destination(id String)\nAS SELECT id FROM my_table;\n\n\n-- Beautify SQL:\nCREATE LIVE VIEW my_live_view\nWITH TIMEOUT 10\nTO my_destination\n(\n  id String\n)\nAS SELECT\n  id\nFROM\n  my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_materialized_view_basic.sql",
    "content": "-- Origin SQL:\nCREATE\nMATERIALIZED VIEW infra_bm.view_name \n    ON CLUSTER 'default_cluster' TO infra_bm.table_name\n(\n  `f1` DateTime64(3), \n  `f2` String, \n  `f3` String, \n  `f4` String, \n  `f5` String, \n  `f6` Int64\n) AS\nSELECT f1,\n       f2,\n       visitParamExtractString(properties, 'f3')   AS f3,\n       visitParamExtractString(properties, 'f4')      AS f4,\n       visitParamExtractString(properties, 'f5')    AS f5,\n    visitParamExtractInt(properties, 'f6') AS f6\nFROM\n    infra_bm.table_name1\nWHERE\n    infra_bm.table_name1.event = 'test-event'\nCOMMENT 'Comment for table';\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW infra_bm.view_name\nON CLUSTER 'default_cluster'\nTO infra_bm.table_name\n(\n  `f1` DateTime64(3),\n  `f2` String,\n  `f3` String,\n  `f4` String,\n  `f5` String,\n  `f6` Int64\n)\nAS\n  SELECT\n    f1,\n    f2,\n    visitParamExtractString(properties, 'f3') AS f3,\n    visitParamExtractString(properties, 'f4') AS f4,\n    visitParamExtractString(properties, 'f5') AS f5,\n    visitParamExtractInt(properties, 'f6') AS f6\n  FROM\n    infra_bm.table_name1\n  WHERE\n    infra_bm.table_name1.event = 'test-event'\nCOMMENT 'Comment for table';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_materialized_view_with_comment_before_as.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table\n(\n    `shop_id` UInt64,\n    `event_type` LowCardinality(String),\n    `created_at` DateTime64(9)\n)\nCOMMENT '{\"blueprint_hash\":\"abc123\",\"timestamp\":\"2026-04-08T12:00:00Z\"}'\nAS SELECT\n    shop_id,\n    event_type,\n    created_at\nFROM db.src_table;\n\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW db.mv_with_comment\nTO db.dst_table\n(\n  `shop_id` UInt64,\n  `event_type` LowCardinality(String),\n  `created_at` DateTime64(9)\n)\nAS\n  SELECT\n    shop_id,\n    event_type,\n    created_at\n  FROM\n    db.src_table\nCOMMENT '{\"blueprint_hash\":\"abc123\",\"timestamp\":\"2026-04-08T12:00:00Z\"}';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_materialized_view_with_definer.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export\n(\n    `timestamp` DateTime64(9),\n    `field_1` String,\n    `field_2` String,\n)\nDEFINER = default SQL SECURITY DEFINER\nAS (SELECT\n    timestamp,\n    field_1,\n    field_2,\nFROM event_table\nWHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1)))\nCOMMENT 'Test comment'\n\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE\nAPPEND\nTO events_export\n(\n  `timestamp` DateTime64(9),\n  `field_1` String,\n  `field_2` String\n)\nDEFINER = default\nSQL SECURITY DEFINER\nAS\n  (SELECT\n    timestamp,\n    field_1,\n    field_2,\n    FROM AS event_table\n  WHERE\n    toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1)))\nCOMMENT 'Test comment';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_materialized_view_with_empty_table_schema.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW test.t0 on cluster default_cluster\nENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}')\nPARTITION BY toYYYYMM(f0)\nORDER BY (f0)\nPOPULATE AS\nselect f0,f1,f2,coalesce(f0,f1) as f333\nfrom\n    (select\n         f0,f1,f2,\n         ROW_NUMBER() over(partition by f0 order by coalesce(f1,f2)) as rn\n     from test.t\n     where f3 in ('foo', 'bar', 'test')\n       and env ='test'\n    ) as tmp\nwhere rn = 1;\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW test.t0\nON CLUSTER default_cluster\nENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}')\nORDER BY\n  (f0)\nPARTITION BY toYYYYMM(f0)\nPOPULATE\nAS\n  SELECT\n    f0,\n    f1,\n    f2,\n    coalesce(f0, f1) AS f333\n  FROM\n    (SELECT\n      f0,\n      f1,\n      f2,\n      ROW_NUMBER() OVER (PARTITION BY f0 ORDER BY\n        coalesce(f1, f2)) AS rn\n    FROM\n      test.t\n    WHERE\n      f3 IN ('foo', 'bar', 'test')\n    AND\n      env = 'test') AS tmp\n  WHERE\n    rn = 1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_materialized_view_with_gcs.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW database_name.view_name\n        REFRESH EVERY 5 MINUTE TO database_name.table_name AS\n        SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/');\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW database_name.view_name\nREFRESH EVERY 5 MINUTE\nTO database_name.table_name\nAS\n  SELECT\n    *\n  FROM\n    gcs(gcs_creds, url='https://storage.googleapis.com/some-bucket/some-path/');\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_materialized_view_with_refresh.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE\nRANDOMIZE FOR 1 SECOND\nDEPENDS ON  table_v5\nSETTINGS\n    randomize_for = 1,\n    randomize_offset = 10,\n    randomize_period = 1\nAPPEND TO target_table_name\nEMPTY\nAS SELECT\n    `field_1`,\n    `field_2`,\n    `field_3`,\nFROM table_v5\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE\nRANDOMIZE FOR 1 SECOND\nDEPENDS ON table_v5\nSETTINGS\n  randomize_for=1,\n  randomize_offset=10,\n  randomize_period=1\nAPPEND\nTO target_table_name\nEMPTY\nAS\n  SELECT\n    `field_1`,\n    `field_2`,\n    `field_3`,\n    FROM AS table_v5;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_mv_with_not_op.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW infra_bm.view_name\n    ON CLUSTER 'default_cluster' TO infra_bm.table_name\n(\n  `f1` DateTime64(3),\n  `f2` String,\n  `f3` String,\n  `f4` String,\n  `f5` String,\n  `f6` Int64\n) AS\nSELECT f1,\n       f2,\n       visitParamExtractString(properties, 'f3') AS f3,\n       visitParamExtractString(properties, 'f4') AS f4,\n       visitParamExtractString(properties, 'f5') AS f5,\n       visitParamExtractInt(properties, 'f6') AS f6\nFROM infra_bm.table_name1\nWHERE infra_bm.table_name1.event = 'test-event' AND\n    NOT isZeroOrNull(f2) AND f6-2 > 0\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW infra_bm.view_name\nON CLUSTER 'default_cluster'\nTO infra_bm.table_name\n(\n  `f1` DateTime64(3),\n  `f2` String,\n  `f3` String,\n  `f4` String,\n  `f5` String,\n  `f6` Int64\n)\nAS\n  SELECT\n    f1,\n    f2,\n    visitParamExtractString(properties, 'f3') AS f3,\n    visitParamExtractString(properties, 'f4') AS f4,\n    visitParamExtractString(properties, 'f5') AS f5,\n    visitParamExtractInt(properties, 'f6') AS f6\n  FROM\n    infra_bm.table_name1\n  WHERE\n    infra_bm.table_name1.event = 'test-event'\n  AND\n    NOT isZeroOrNull(f2)\n  AND\n    f6 - 2 > 0;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_mv_with_order_by.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nORDER BY (id)\nAS\nSELECT * FROM test_table;\n\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nAS\nSELECT * FROM test_table;\n\n-- Beautify SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nORDER BY\n  (id)\nPRIMARY KEY (id)\nAS\n  SELECT\n    *\n  FROM\n    test_table;\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nAS\n  SELECT\n    *\n  FROM\n    test_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_named_collection_basic.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config\nAS url = 'http://local-minio:9000/*',\naccess_key_id = 'minioadmin',\nsecret_access_key = 'minioadmin';\n\n\n-- Beautify SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_named_collection_simple.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION my_collection\nAS key1 = 'value1',\nkey2 = 'value2';\n\n\n-- Beautify SQL:\nCREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_named_collection_with_cluster.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster\nAS key1 = 'value1' OVERRIDABLE,\nkey2 = 'value2' NOT OVERRIDABLE,\nkey3 = 'value3';\n\n\n-- Beautify SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_named_collection_with_overridable.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION test_collection\nAS url = 'http://example.com' OVERRIDABLE,\naccess_key = 'key123' NOT OVERRIDABLE,\nsecret_key = 'secret456';\n\n\n-- Beautify SQL:\nCREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_or_replace.sql",
    "content": "-- Origin SQL:\n-- It's a short link events table\n/**\n    * @name Short link events\n    * @description It's a short link events table\n */\nCREATE OR REPLACE TABLE IF NOT EXISTS test.events_local (\n    f0 String,\n    f1 String CODEC(ZSTD(1)),\n    f2 VARCHAR(255),\n) ENGINE = MergeTree\nPRIMARY KEY (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f1)\nTTL f1 + INTERVAL 6 MONTH\nORDER BY (f1,f2)\nCOMMENT 'Comment for table';\n\nCREATE OR REPLACE VIEW IF NOT EXISTS my_view(col1 String, col2 String)\nAS\nSELECT\n    id,\n    name\nFROM\n    my_table;\n\nCREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y;\n\n-- Beautify SQL:\nCREATE OR REPLACE TABLE IF NOT EXISTS test.events_local\n(\n  f0 String,\n  f1 String CODEC(ZSTD(1)),\n  f2 VARCHAR(255)\n)\nENGINE = MergeTree\nORDER BY\n  (f1, f2)\nPARTITION BY toYYYYMMDD(f1)\nPRIMARY KEY (f0, f1, f2)\nTTL f1 + INTERVAL 6 MONTH\nCOMMENT 'Comment for table';\nCREATE OR REPLACE VIEW IF NOT EXISTS my_view (\n  col1 String,\n  col2 String\n) AS SELECT\n  id,\n  name\nFROM\n  my_table;\nCREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_role.sql",
    "content": "-- Origin SQL:\n-- Tags: no-parallel\n\nCREATE ROLE r1_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2;\nCREATE ROLE r1_01293 SETTINGS NONE;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nCREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nCREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nCREATE ROLE r6_01293 SETTINGS max_memory_usage CONST;\nCREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nCREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nCREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 SETTINGS readonly=1;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nCREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nCREATE ROLE r5_01293 SETTINGS NONE;\nCREATE ROLE r1_01293@'%';\nCREATE ROLE r2_01293@'%.myhost.com';\n\n-- Beautify SQL:\nCREATE ROLE r1_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2;\nCREATE ROLE r1_01293\nSETTINGS\n  NONE;\nCREATE ROLE r2_01293\nSETTINGS\n  PROFILE 'default';\nCREATE ROLE r3_01293\nSETTINGS\n  max_memory_usage=5000000;\nCREATE ROLE r4_01293\nSETTINGS\n  max_memory_usage\n  MIN=5000000;\nCREATE ROLE r5_01293\nSETTINGS\n  max_memory_usage\n  MAX=5000000;\nCREATE ROLE r6_01293\nSETTINGS\n  max_memory_usage\n  CONST;\nCREATE ROLE r7_01293\nSETTINGS\n  max_memory_usage\n  WRITABLE;\nCREATE ROLE r8_01293\nSETTINGS\n  max_memory_usage=5000000\n  MIN 4000000\n  MAX 6000000\n  CONST;\nCREATE ROLE r9_01293\nSETTINGS\n  PROFILE 'default',\n  max_memory_usage=5000000\n  WRITABLE;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293\nSETTINGS\n  readonly=1;\nCREATE ROLE r2_01293\nSETTINGS\n  PROFILE 'default';\nCREATE ROLE r3_01293\nSETTINGS\n  max_memory_usage=5000000\n  MIN 4000000\n  MAX 6000000\n  WRITABLE;\nCREATE ROLE r4_01293\nSETTINGS\n  PROFILE 'default',\n  max_memory_usage=5000000,\n  readonly=1;\nCREATE ROLE r5_01293\nSETTINGS\n  NONE;\nCREATE ROLE r1_01293@'%';\nCREATE ROLE r2_01293@'%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_as_remote_function.sql",
    "content": "-- Origin SQL:\n-- CREATE TABLE with columns AS table function (remoteSecure)\nCREATE TABLE test_remote\n(\n    id UInt64,\n    name String,\n    value Int32\n)\nAS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password');\n\n-- Simpler test case with remote()\nCREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table');\n\n\n-- Beautify SQL:\nCREATE TABLE test_remote\n(\n  id UInt64,\n  name String,\n  value Int32\n)\nAS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password');\nCREATE TABLE test_table\n(\n  id UInt64,\n  name String\n)\nAS remote('localhost', 'db', 'source_table');\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_basic.sql",
    "content": "-- Origin SQL:\n-- It's a short link events table\n/**\n    * @name Short link events\n    * @description It's a short link events table\n */\nCREATE TABLE IF NOT EXISTS test.events_local (\n    f0 String,\n    f1 String CODEC(ZSTD(1)),\n    f2 VARCHAR(255),\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Nested (\n        f70 UInt32,\n        f71 UInt32,\n        f72 DateTime,\n        f73 Int64,\n        f74 Int64,\n        f75 String\n    ),\n    f8 Datetime DEFAULT now(),\n    f9 String MATERIALIZED toString(f7['f70']),\n    f10 String ALIAS f11,\n    f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello'),\n) ENGINE = MergeTree\nPRIMARY KEY (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f3)\nTTL f3 + INTERVAL 6 MONTH\nORDER BY (f1,f2,f3)\nCOMMENT 'Comment for table';\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test.events_local\n(\n  f0 String,\n  f1 String CODEC(ZSTD(1)),\n  f2 VARCHAR(255),\n  f3 Datetime,\n  f4 Datetime,\n  f5 Map(String, String),\n  f6 String,\n  f7 Nested(f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String),\n  f8 Datetime DEFAULT now(),\n  f9 String MATERIALIZED toString(f7['f70']),\n  f10 String ALIAS f11,\n  f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c,  SKIP REGEXP 'hello')\n)\nENGINE = MergeTree\nORDER BY\n  (f1, f2, f3)\nPARTITION BY toYYYYMMDD(f3)\nPRIMARY KEY (f0, f1, f2)\nTTL f3 + INTERVAL 6 MONTH\nCOMMENT 'Comment for table';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_codec_no_args.sql",
    "content": "-- Origin SQL:\nCREATE TABLE shark_attacks (\n    timestamp DateTime CODEC(DoubleDelta),\n);\n\n-- Beautify SQL:\nCREATE TABLE shark_attacks\n(\n  timestamp DateTime CODEC(DoubleDelta)\n);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_json_typehints.sql",
    "content": "-- Origin SQL:\nCREATE TABLE t (\n    j JSON(message String, a.b UInt64, max_dynamic_paths=0, SKIP x, SKIP REGEXP 're')\n) ENGINE = MergeTree\nORDER BY tuple();\n\n\n\n\n-- Beautify SQL:\nCREATE TABLE t\n(\n  j JSON(max_dynamic_paths=0, message String, a.b UInt64, SKIP x,  SKIP REGEXP 're')\n)\nENGINE = MergeTree\nORDER BY\n  tuple();\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_codec_delta.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test_local\n(\n `id` UInt64 CODEC(Delta, ZSTD(1)),\n `api_id` UInt64 CODEC(ZSTD(1)),\n `app_id` UInt64 CODEC(Delta(9), ZSTD(1)),\n `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)),\n `guage` Float64 CODEC(Gorilla, LZ4),\n `value` UInt64 CODEC(T64, LZ4),\n `timestamp` DateTime64(9) CODEC(ZSTD(1)),\n INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nPARTITION BY toStartOfHour(`timestamp`)\nORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test_local\n(\n  `id` UInt64 CODEC(Delta, ZSTD(1)),\n  `api_id` UInt64 CODEC(ZSTD(1)),\n  `app_id` UInt64 CODEC(Delta(9), ZSTD(1)),\n  `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)),\n  `guage` Float64 CODEC(Gorilla, LZ4),\n  `value` UInt64 CODEC(T64, LZ4),\n  `timestamp` DateTime64(9) CODEC(ZSTD(1)),\n  INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nORDER BY\n  (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nPARTITION BY toStartOfHour(`timestamp`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS\n  execute_merges_on_single_replica_time_threshold=1200,\n  index_granularity=16384,\n  max_bytes_to_merge_at_max_space_in_pool=64424509440,\n  storage_policy='main',\n  ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_enum_fields.sql",
    "content": "-- Origin SQL:\nCREATE TABLE t0 on cluster default_cluster\n(\n    `method` Enum8('GET'=1 , 'POST'=2, 'HEAD'=3, 'PUT'=4,'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)),\n    `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD)\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nPARTITION BY toDate(timestamp)\nORDER BY (method,timestamp)\nTTL toDate(timestamp) + toIntervalDay(3)\nSETTINGS index_granularity = 8192;\n\n-- Beautify SQL:\nCREATE TABLE t0 ON CLUSTER default_cluster\n(\n  `method` Enum8('GET'=1, 'POST'=2, 'HEAD'=3, 'PUT'=4, 'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)),\n  `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD)\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nORDER BY\n  (method, timestamp)\nPARTITION BY toDate(timestamp)\nTTL toDate(timestamp) + toIntervalDay(3)\nSETTINGS\n  index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_index.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test_local\n(\n `common.id` String CODEC(ZSTD(1)),\n `id` UInt64 CODEC(Delta, ZSTD(1)),\n `idx` UInt64 CODEC(Delta, ZSTD(1)),\n `api_id` UInt64 CODEC(ZSTD(1)),\n `arr` Array(Int64),\n `content` String CODEC(ZSTD(1)),\n `output` String,\n INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1,\n INDEX id_idx id TYPE minmax GRANULARITY 10,\n INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1,\n INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2,\n INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3,\n INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1,\n INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nPARTITION BY toStartOfHour(`timestamp`)\nORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test_local\n(\n  `common.id` String CODEC(ZSTD(1)),\n  `id` UInt64 CODEC(Delta, ZSTD(1)),\n  `idx` UInt64 CODEC(Delta, ZSTD(1)),\n  `api_id` UInt64 CODEC(ZSTD(1)),\n  `arr` Array(Int64),\n  `content` String CODEC(ZSTD(1)),\n  `output` String,\n  INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1,\n  INDEX id_idx id TYPE minmax GRANULARITY 10,\n  INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1,\n  INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2,\n  INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3,\n  INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1,\n  INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nORDER BY\n  (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nPARTITION BY toStartOfHour(`timestamp`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS\n  execute_merges_on_single_replica_time_threshold=1200,\n  index_granularity=16384,\n  max_bytes_to_merge_at_max_space_in_pool=64424509440,\n  storage_policy='main',\n  ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_keyword_partition_by.sql",
    "content": "-- Origin SQL:\nCREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' (\n    `date` Date,\n    `f1` String,\n    `f2` String,\n    `f3` UInt64\n    ) ENGINE = ReplacingMergeTree\n    PARTITION BY date\n    ORDER BY (f1, f2)\n    SETTINGS index_granularity = 8192;\n\n-- Beautify SQL:\nCREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0'\n(\n  `date` Date,\n  `f1` String,\n  `f2` String,\n  `f3` UInt64\n)\nENGINE = ReplacingMergeTree\nORDER BY\n  (f1, f2)\nPARTITION BY date\nSETTINGS\n  index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_null_engine.sql",
    "content": "-- Origin SQL:\nCREATE TABLE logs.t0 on cluster default\n(\n    `trace_id` String CODEC(ZSTD(1)),\n    INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64\n) ENGINE = Null();\n\n-- Beautify SQL:\nCREATE TABLE logs.t0 ON CLUSTER default\n(\n  `trace_id` String CODEC(ZSTD(1)),\n  INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64\n)\nENGINE = Null();\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_nullable.sql",
    "content": "-- Origin SQL:\nCREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5`\n    UUID '27673372-7973-44f5-a767-33727973c4f5' (\n    `f0` String,\n    `f1` String,\n    `f2` LowCardinality(String),\n    `f3` LowCardinality(String),\n    `f4` DateTime64(3),\n    `f5` Nullable(DateTime64(3)),\n    `succeed_at` Nullable(DateTime64(3))\n) ENGINE = MergeTree\nPARTITION BY xxHash32(tag_id) % 20\nORDER BY label_id\nSETTINGS index_granularity = 8192;\n\n\n-- Beautify SQL:\nCREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5'\n(\n  `f0` String,\n  `f1` String,\n  `f2` LowCardinality(String),\n  `f3` LowCardinality(String),\n  `f4` DateTime64(3),\n  `f5` Nullable(DateTime64(3)),\n  `succeed_at` Nullable(DateTime64(3))\n)\nENGINE = MergeTree\nORDER BY\n  label_id\nPARTITION BY xxHash32(tag_id) % 20\nSETTINGS\n  index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_on_clsuter.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster'\n(\n  f0 String,\n  f1 String,\n  f2 String,\n  f3 Datetime,\n  f4 Datetime,\n  f5 Map(String, String),\n  f6 String,\n  f7 Datetime DEFAULT now()\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nORDER BY\n  (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f3)\nTTL f3 + INTERVAL 6 MONTH;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_projection.sql",
    "content": "-- Origin SQL:\nCREATE TABLE events\n(\n    `event_time` DateTime,\n    `event_id` UInt64,\n    `user_id` UInt64,\n    `huge_string` String,\n    PROJECTION order_by_user_id\n    (\n        SELECT\n            _part_offset\n        ORDER BY user_id\n    )\n)\nENGINE = MergeTree()\nORDER BY (event_id); \n\n-- Beautify SQL:\nCREATE TABLE events\n(\n  `event_time` DateTime,\n  `event_id` UInt64,\n  `user_id` UInt64,\n  `huge_string` String,\n  PROJECTION order_by_user_id (SELECT _part_offset ORDER BY user_id)\n)\nENGINE = MergeTree()\nORDER BY\n  (event_id);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_projection_group_by_only.sql",
    "content": "-- Origin SQL:\nCREATE TABLE events\n(\n    `event_time` DateTime,\n    `event_type` String,\n    `user_id` UInt64,\n    `value` Float64,\n    PROJECTION hourly_aggregates\n    (\n        SELECT\n            toStartOfHour(event_time) AS hour,\n            event_type,\n            count() AS event_count,\n            sum(value) AS total_value\n        GROUP BY hour, event_type\n    )\n)\nENGINE = MergeTree()\nORDER BY (event_time, event_type);\n\n\n-- Beautify SQL:\nCREATE TABLE events\n(\n  `event_time` DateTime,\n  `event_type` String,\n  `user_id` UInt64,\n  `value` Float64,\n  PROJECTION hourly_aggregates (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY\n    hour, event_type)\n)\nENGINE = MergeTree()\nORDER BY\n  (event_time, event_type);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_qbit.sql",
    "content": "-- Origin SQL:\nCREATE TABLE test.qbit_example (\n    id UInt32,\n    vec QBit(Float32, 8)\n) ENGINE = Memory;\n\n\n-- Beautify SQL:\nCREATE TABLE test.qbit_example\n(\n  id UInt32,\n  vec QBit(Float32, 8)\n)\nENGINE = Memory;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_sample_by.sql",
    "content": "-- Origin SQL:\nCREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e'\n(\n    `f0` DateTime,\n    `f1` UInt32,\n    `f3` UInt32\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}')\nPARTITION BY toYYYYMM(timestamp)\nORDER BY (contractid, toDate(timestamp), userid)\nSAMPLE BY userid\nSETTINGS index_granularity = 8192;\n\n-- Beautify SQL:\nCREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e'\n(\n  `f0` DateTime,\n  `f1` UInt32,\n  `f3` UInt32\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}')\nORDER BY\n  (contractid, toDate(timestamp), userid)\nPARTITION BY toYYYYMM(timestamp)\nSAMPLE BY userid\nSETTINGS\n  index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_ttl_policy.sql",
    "content": "-- Origin SQL:\nCREATE TABLE tab\n(\n    d DateTime,\n    a Int\n)\n    ENGINE = MergeTree\nPARTITION BY toYYYYMM(d)\nORDER BY d\nTTL d + INTERVAL 1 MONTH DELETE,\n    d + INTERVAL 1 WEEK TO VOLUME 'aaa',\n    d + INTERVAL 2 WEEK TO DISK 'bbb';\n\n\nCREATE TABLE table_with_where\n(\n    d DateTime,\n    a Int\n)\n    ENGINE = MergeTree\nPARTITION BY toYYYYMM(d)\nORDER BY d\nTTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1;\n\nCREATE TABLE table_for_recompression\n(\n    d DateTime,\n    key UInt64,\n    value String\n) ENGINE MergeTree()\nORDER BY tuple()\nPARTITION BY key\nTTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10))\nSETTINGS min_rows_for_wide_part = 0, min_bytes_for_wide_part = 0, allow_experimental_replacing_merge_with_cleanup = true;\n\n\n-- Beautify SQL:\nCREATE TABLE tab\n(\n  d DateTime,\n  a Int\n)\nENGINE = MergeTree\nORDER BY\n  d\nPARTITION BY toYYYYMM(d)\nTTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb';\nCREATE TABLE table_with_where\n(\n  d DateTime,\n  a Int\n)\nENGINE = MergeTree\nORDER BY\n  d\nPARTITION BY toYYYYMM(d)\nTTL d + INTERVAL 1 MONTH DELETE WHERE\n  toDayOfWeek(d) = 1;\nCREATE TABLE table_for_recompression\n(\n  d DateTime,\n  key UInt64,\n  value String\n)\nENGINE = MergeTree()\nORDER BY\n  tuple()\nPARTITION BY key\nTTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10))\nSETTINGS\n  min_rows_for_wide_part=0,\n  min_bytes_for_wide_part=0,\n  allow_experimental_replacing_merge_with_cleanup=true;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_tuple_fields.sql",
    "content": "-- Origin SQL:\nCREATE TABLE t0 on cluster default_cluster\n(\n    `tup0` Tuple(),\n    `tup1` Tuple(String, Int64),\n    `tup2` Tuple(String, Tuple(String, String)),\n    `tup3` Tuple(a String, cd Tuple(c String, d String))\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nORDER BY (tup1, tup2, tup3)\nSETTINGS index_granularity = 8192;\n\n\n-- Beautify SQL:\nCREATE TABLE t0 ON CLUSTER default_cluster\n(\n  `tup0` Tuple(),\n  `tup1` Tuple(String, Int64),\n  `tup2` Tuple(String, Tuple(String, String)),\n  `tup3` Tuple(a String, cd Tuple(c String, d String))\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nORDER BY\n  (tup1, tup2, tup3)\nSETTINGS\n  index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_table_with_uuid.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster'\n(\n  f0 String,\n  f1 String,\n  f2 String,\n  f3 Datetime,\n  f4 Datetime,\n  f5 Map(String, String),\n  f6 String,\n  f7 Datetime DEFAULT now()\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nORDER BY\n  (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f3)\nTTL f3 + INTERVAL 6 MONTH;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_user.sql",
    "content": "-- Origin SQL:\n-- Basic CREATE USER tests\n\nCREATE USER user1;\nCREATE USER IF NOT EXISTS user2;\nCREATE USER OR REPLACE user3;\nCREATE USER user4, user5;\n\n-- CREATE USER with authentication\nCREATE USER user6 NOT IDENTIFIED;\nCREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123';\nCREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123';\nCREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server';\nCREATE USER user10 IDENTIFIED WITH kerberos;\nCREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM';\n\n-- CREATE USER with VALID UNTIL\nCREATE USER user33 VALID UNTIL '2026-12-12 00:00:00';\nCREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15';\nCREATE USER user35 VALID UNTIL 'infinity';\n\n-- CREATE USER with host restrictions\nCREATE USER user12 HOST LOCAL;\nCREATE USER user13 HOST ANY;\nCREATE USER user14 HOST NONE;\nCREATE USER user15 HOST NAME 'localhost';\nCREATE USER user16 HOST REGEXP '.*\\.example\\.com';\nCREATE USER user17 HOST IP '192.168.1.1';\nCREATE USER user18 HOST LIKE 'test%';\n\n-- CREATE USER with default roles\nCREATE USER user19 DEFAULT ROLE role1;\nCREATE USER user20 DEFAULT ROLE role1, role2;\nCREATE USER user21 DEFAULT ROLE NONE;\n\n-- CREATE USER with default database\nCREATE USER user22 DEFAULT DATABASE test_db;\nCREATE USER user23 DEFAULT DATABASE NONE;\n\n-- CREATE USER with grantees\nCREATE USER user24 GRANTEES user1;\nCREATE USER user25 GRANTEES user1, user2;\nCREATE USER user26 GRANTEES ANY;\nCREATE USER user27 GRANTEES NONE;\nCREATE USER user28 GRANTEES user1, user2 EXCEPT user3;\n\n-- CREATE USER with settings\nCREATE USER user29 SETTINGS max_memory_usage=5000000;\nCREATE USER user30 SETTINGS PROFILE 'default';\nCREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000;\n\n-- Complex CREATE USER with multiple clauses\nCREATE USER user32\n    IDENTIFIED WITH plaintext_password BY 'password'\n    VALID UNTIL '2025-12-31'\n    HOST NAME 'localhost'\n    DEFAULT ROLE role1, role2\n    DEFAULT DATABASE test_db\n    GRANTEES user1, user2 EXCEPT user3\n    SETTINGS max_memory_usage=5000000, readonly=1;\n\n-- Beautify SQL:\nCREATE USER user1;\nCREATE USER IF NOT EXISTS user2;\nCREATE USER OR REPLACE user3;\nCREATE USER user4, user5;\nCREATE USER user6\nNOT IDENTIFIED;\nCREATE USER user7\nIDENTIFIED WITH plaintext_password BY 'password123';\nCREATE USER user8\nIDENTIFIED WITH sha256_password BY 'hash123';\nCREATE USER user9\nIDENTIFIED\nWITH ldap SERVER 'ldap_server';\nCREATE USER user10\nIDENTIFIED\nWITH kerberos;\nCREATE USER user11\nIDENTIFIED\nWITH kerberos REALM 'EXAMPLE.COM';\nCREATE USER user33\nVALID UNTIL '2026-12-12 00:00:00';\nCREATE USER user34\nIDENTIFIED WITH plaintext_password BY 'password123'\nVALID UNTIL '2026-06-15';\nCREATE USER user35\nVALID UNTIL 'infinity';\nCREATE USER user12\nHOST LOCAL;\nCREATE USER user13\nHOST ANY;\nCREATE USER user14\nHOST NONE;\nCREATE USER user15\nHOST NAME 'localhost';\nCREATE USER user16\nHOST REGEXP '.*\\.example\\.com';\nCREATE USER user17\nHOST IP '192.168.1.1';\nCREATE USER user18\nHOST LIKE 'test%';\nCREATE USER user19\nDEFAULT ROLE role1;\nCREATE USER user20\nDEFAULT ROLE role1, role2;\nCREATE USER user21\nDEFAULT ROLE NONE;\nCREATE USER user22\nDEFAULT DATABASE test_db;\nCREATE USER user23\nDEFAULT DATABASE NONE;\nCREATE USER user24\nGRANTEES user1;\nCREATE USER user25\nGRANTEES user1, user2;\nCREATE USER user26\nGRANTEES ANY;\nCREATE USER user27\nGRANTEES NONE;\nCREATE USER user28\nGRANTEES user1, user2\nEXCEPT user3;\nCREATE USER user29\nSETTINGS\n  max_memory_usage=5000000;\nCREATE USER user30\nSETTINGS\n  PROFILE 'default';\nCREATE USER user31\nSETTINGS\n  readonly=1,\n  max_memory_usage=5000000;\nCREATE USER user32\nIDENTIFIED WITH plaintext_password BY 'password'\nVALID UNTIL '2025-12-31'\nHOST NAME 'localhost'\nDEFAULT ROLE role1, role2\nDEFAULT DATABASE test_db\nGRANTEES user1, user2\nEXCEPT user3\nSETTINGS\n  max_memory_usage=5000000,\n  readonly=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_view_basic.sql",
    "content": "-- Origin SQL:\nCREATE VIEW IF NOT EXISTS my_view(col1 String, col2 String)\nAS\nSELECT\n    id,\n    name\nFROM\n    my_table;\n\n-- Beautify SQL:\nCREATE VIEW IF NOT EXISTS my_view (\n  col1 String,\n  col2 String\n) AS SELECT\n  id,\n  name\nFROM\n  my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_view_on_cluster_with_uuid.sql",
    "content": "-- Origin SQL:\nCREATE VIEW IF NOT EXISTS cluster_name.my_view\n        UUID '3493e374-e2bb-481b-b493-e374e2bb981b'\n        ON CLUSTER 'my_cluster'\nAS (\n    SELECT\n    column1,\n    column2\n    FROM\n    my_other_table\n);\n\n-- Beautify SQL:\nCREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS (SELECT\n  column1,\n  column2\nFROM\n  my_other_table);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_view_with_comment.sql",
    "content": "-- Origin SQL:\nCREATE VIEW IF NOT EXISTS db.my_view\n(\n    `id` Int64,\n    `name` String\n)\nCOMMENT '{\"blueprint_hash\":\"abc123\"}'\nAS SELECT\n    id,\n    name\nFROM db.my_table;\n\n\n-- Beautify SQL:\nCREATE VIEW IF NOT EXISTS db.my_view (\n  `id` Int64,\n  `name` String\n) COMMENT '{\"blueprint_hash\":\"abc123\"}' AS SELECT\n  id,\n  name\nFROM\n  db.my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/create_with_time_zone.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster\n(\n    `f0` Array(Tuple(\n        f00 DateTime64(9, 'UTC'),\n        f01 String,\n        f02 Map(String, String),\n        f03 Map(String, Float64),\n        f04 Map(String, BOOL))) CODEC(ZSTD(1)\n    ),\n    `f1` UInt64 CODEC(Delta(8), LZ4),\n    `f2` FixedString(16) CODEC(LZ4),\n    `f3` FixedString(8) CODEC(LZ4),\n    `f4` FixedString(8) CODEC(LZ4),\n    `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4),\n    `f6` UInt64 CODEC(Delta(8), LZ4),\n    `f7` LowCardinality(String) CODEC(ZSTD(1)),\n    `f8` String CODEC(ZSTD(1)),\n    `f9` LowCardinality(String) CODEC(ZSTD(1)),\n    `f10` String CODEC(ZSTD(1)),\n    `f11` LowCardinality(String) CODEC(ZSTD(1)),\n    `f12` LowCardinality(String) CODEC(ZSTD(1)),\n    `f13` String CODEC(ZSTD(1)),\n    `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n    `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n    `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)),\n    `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)),\n    `f18` Array(Tuple(\n        f180 FixedString(16),\n        f181 FixedString(8),\n        f182 String,\n        f183 Map(String, String))) CODEC(ZSTD(1)),\n        `f184` String CODEC(ZSTD(1)),\n        `f185` String CODEC(ZSTD(1)),\n        `f186` String CODEC(ZSTD(1)),\n        `f187` UInt32 CODEC(ZSTD(1)),\n        `f188` DATETIME DEFAULT now(),\n        INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1,\n        INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1,\n        INDEX idx_f2 f2 TYPE minmax GRANULARITY 1,\n        INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4,\n        INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1,\n        INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4\n    )\n    ENGINE = MergeTree\n    PARTITION BY toDate(timestamp)\n    ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp))\n    TTL toDate(timestamp) + toIntervalDay(15)\n    SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1\n\n-- Beautify SQL:\nCREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster\n(\n  `f0` Array(Tuple(f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1)),\n  `f1` UInt64 CODEC(Delta(8), LZ4),\n  `f2` FixedString(16) CODEC(LZ4),\n  `f3` FixedString(8) CODEC(LZ4),\n  `f4` FixedString(8) CODEC(LZ4),\n  `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4),\n  `f6` UInt64 CODEC(Delta(8), LZ4),\n  `f7` LowCardinality(String) CODEC(ZSTD(1)),\n  `f8` String CODEC(ZSTD(1)),\n  `f9` LowCardinality(String) CODEC(ZSTD(1)),\n  `f10` String CODEC(ZSTD(1)),\n  `f11` LowCardinality(String) CODEC(ZSTD(1)),\n  `f12` LowCardinality(String) CODEC(ZSTD(1)),\n  `f13` String CODEC(ZSTD(1)),\n  `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n  `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n  `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)),\n  `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)),\n  `f18` Array(Tuple(f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)),\n  `f184` String CODEC(ZSTD(1)),\n  `f185` String CODEC(ZSTD(1)),\n  `f186` String CODEC(ZSTD(1)),\n  `f187` UInt32 CODEC(ZSTD(1)),\n  `f188` DATETIME DEFAULT now(),\n  INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1,\n  INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1,\n  INDEX idx_f2 f2 TYPE minmax GRANULARITY 1,\n  INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4,\n  INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1,\n  INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4\n)\nENGINE = MergeTree\nORDER BY\n  (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp))\nPARTITION BY toDate(timestamp)\nTTL toDate(timestamp) + toIntervalDay(15)\nSETTINGS\n  index_granularity=8192,\n  ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/desc_table_with_table_keyword.sql",
    "content": "-- Origin SQL:\nDESC TABLE mytable\n\n-- Beautify SQL:\nDESCRIBE TABLE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/desc_table_without_table_keyword.sql",
    "content": "-- Origin SQL:\nDESC mytable\n\n-- Beautify SQL:\nDESCRIBE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/describe_table_with_table_keyword.sql",
    "content": "-- Origin SQL:\nDESCRIBE TABLE mytable\n\n-- Beautify SQL:\nDESCRIBE TABLE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/describe_table_without_table_keyword.sql",
    "content": "-- Origin SQL:\nDESCRIBE mytable\n\n-- Beautify SQL:\nDESCRIBE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/drop_database.sql",
    "content": "-- Origin SQL:\nDROP DATABASE IF EXISTS datbase_name;\n\n\n-- Beautify SQL:\nDROP DATABASE IF EXISTS datbase_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/drop_role.sql",
    "content": "-- Origin SQL:\nDROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293;\nDROP ROLE IF EXISTS r2_01293_renamed;\nDROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com';\n\n\n-- Beautify SQL:\nDROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293;\nDROP ROLE IF EXISTS r2_01293_renamed;\nDROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/drop_table_basic.sql",
    "content": "-- Origin SQL:\nDROP TABLE IF EXISTS test.table_name;\n\n\n-- Beautify SQL:\nDROP TABLE IF EXISTS test.table_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/drop_table_with_no_delay.sql",
    "content": "-- Origin SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY;\n\n\n-- Beautify SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/drop_table_with_on_clsuter.sql",
    "content": "-- Origin SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n\n\n-- Beautify SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/grant_privilege.sql",
    "content": "-- Origin SQL:\nGRANT SELECT(x,y) ON db.table TO john;\nGRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION;\nGRANT SELECT(x,y) ON db.* TO john;\nGRANT SELECT(x,y) ON *.table TO john;\nGRANT SELECT(x,y) ON *.* TO john;\nGRANT SELECT(x,y) ON *.table TO CURRENT_USER;\nGRANT SELECT(x,y) ON *.table TO CURRENT_USER,john,mary;\nGRANT ALL ON *.* TO admin_role WITH GRANT OPTION;\nGRANT SELECT,INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT(x, y, z),INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT, dictGet ON *.*  TO select_all_role;\nGRANT ADMIN OPTION ON *.*  TO select_all_role;\n\n\n\n-- Beautify SQL:\nGRANT SELECT(x, y) ON db.table TO john;\nGRANT SELECT(x, y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION;\nGRANT SELECT(x, y) ON db.* TO john;\nGRANT SELECT(x, y) ON *.table TO john;\nGRANT SELECT(x, y) ON *.* TO john;\nGRANT SELECT(x, y) ON *.table TO CURRENT_USER;\nGRANT SELECT(x, y) ON *.table TO CURRENT_USER, john, mary;\nGRANT ALL ON *.* TO admin_role WITH GRANT OPTION;\nGRANT SELECT, INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT(x, y, z), INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT, dictGet ON *.* TO select_all_role;\nGRANT ADMIN OPTION ON *.* TO select_all_role;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/optimize.sql",
    "content": "-- Origin SQL:\nOPTIMIZE TABLE table DEDUPLICATE; -- all columns\nOPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns\nOPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY);\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex');\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY);\n\n-- Beautify SQL:\nOPTIMIZE TABLE table DEDUPLICATE;\nOPTIMIZE TABLE table DEDUPLICATE BY *;\nOPTIMIZE TABLE table DEDUPLICATE BY colX, colY, colZ;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY);\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex');\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY);\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/rename.sql",
    "content": "-- Origin SQL:\n-- rename table\nRENAME TABLE t1 TO t11;\nRENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME TABLE t1 TO t11, t2 TO t22;\nRENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n-- rename dictionary   \nRENAME DICTIONARY t1 TO t11;\nRENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11, t2 TO t22;\nRENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n-- rename database\nRENAME DATABASE t1 TO t11;\nRENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11, t2 TO t22;\nRENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n\n\n-- Beautify SQL:\nRENAME TABLE t1 TO t11;\nRENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME TABLE t1 TO t11, t2 TO t22;\nRENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11;\nRENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11, t2 TO t22;\nRENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11;\nRENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11, t2 TO t22;\nRENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_create_table.sql",
    "content": "-- Origin SQL:\nSHOW CREATE TABLE mytable\n\n-- Beautify SQL:\nSHOW CREATE TABLE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES\n\n-- Beautify SQL:\nSHOW DATABASES;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_comprehensive.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON\n\n-- Beautify SQL:\nSHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT 'JSON';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_format.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES FORMAT JSON\n\n-- Beautify SQL:\nSHOW DATABASES FORMAT 'JSON';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_format_string.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES FORMAT 'TabSeparated'\n\n-- Beautify SQL:\nSHOW DATABASES FORMAT 'TabSeparated';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_ilike.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES ILIKE 'Test%'\n\n-- Beautify SQL:\nSHOW DATABASES ILIKE 'Test%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_like.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES LIKE 'test%'\n\n-- Beautify SQL:\nSHOW DATABASES LIKE 'test%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_limit.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES LIMIT 10\n\n-- Beautify SQL:\nSHOW DATABASES LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_not_ilike.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES NOT ILIKE 'Temp%'\n\n-- Beautify SQL:\nSHOW DATABASES NOT ILIKE 'Temp%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_not_like.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES NOT LIKE 'temp%'\n\n-- Beautify SQL:\nSHOW DATABASES NOT LIKE 'temp%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_databases_outfile.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES INTO OUTFILE '/tmp/databases.txt'\n\n-- Beautify SQL:\nSHOW DATABASES INTO OUTFILE '/tmp/databases.txt';\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/show_tables.sql",
    "content": "-- Origin SQL:\nSHOW TABLES\n\n-- Beautify SQL:\nSHOW TABLES;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/systems.sql",
    "content": "-- Origin SQL:\nSYSTEM FLUSH LOGS;\nSYSTEM DROP UNCOMPRESSED CACHE;\nSYSTEM DROP FILESYSTEM CACHE;\n\n\n-- Beautify SQL:\nSYSTEM FLUSH LOGS;\nSYSTEM DROP UNCOMPRESSED CACHE;\nSYSTEM DROP FILESYSTEM CACHE;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/truncate_table_basic.sql",
    "content": "-- Origin SQL:\nTRUNCATE TABLE IF EXISTS test.table_name;\n\n\n-- Beautify SQL:\nTRUNCATE TABLE IF EXISTS test.table_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/beautify/truncate_temporary_table_on_clsuter.sql",
    "content": "-- Origin SQL:\nTRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n\n\n-- Beautify SQL:\nTRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/format/bug_001.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS db.table\n            ON CLUSTER 'default_cluster' TO db.table_mv\nAS\nSELECT\n    event_ts,\n    org_id,\n    visitParamExtractString(properties, 'x') AS x,\n    visitParamExtractString(properties, 'y') AS y,\n    visitParamExtractString(properties, 'z') AS z,\n    visitParamExtractString(properties, 'a') AS a,\n    visitParamExtractString(properties, 'b') AS b,\n    visitParamExtractString(properties, 'c') AS c,\n    visitParamExtractString(properties, 'd') AS d,\n    visitParamExtractInt(properties, 'e') AS e,\n    visitParamExtractInt(properties, 'f') AS f\nFROM db.table\nWHERE db.table.event = 'hello';\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS db.table ON CLUSTER 'default_cluster' TO db.table_mv AS SELECT event_ts, org_id, visitParamExtractString(properties, 'x') AS x, visitParamExtractString(properties, 'y') AS y, visitParamExtractString(properties, 'z') AS z, visitParamExtractString(properties, 'a') AS a, visitParamExtractString(properties, 'b') AS b, visitParamExtractString(properties, 'c') AS c, visitParamExtractString(properties, 'd') AS d, visitParamExtractInt(properties, 'e') AS e, visitParamExtractInt(properties, 'f') AS f FROM db.table WHERE db.table.event = 'hello';\n"
  },
  {
    "path": "parser/testdata/ddl/format/check.sql",
    "content": "-- Origin SQL:\nCHECK TABLE test_table;\nCHECK TABLE test_table PARTITION 'col';\n\n\n-- Format SQL:\nCHECK TABLE test_table;\nCHECK TABLE test_table PARTITION 'col';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_database.sql",
    "content": "-- Origin SQL:\nCREATE DATABASE IF NOT EXISTS `test`\n\n-- Format SQL:\nCREATE DATABASE IF NOT EXISTS `test`;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_database_replicated.sql",
    "content": "-- Origin SQL:\nCREATE DATABASE IF NOT EXISTS `test` ENGINE=Replicated('/root/test_local', 'shard', 'replica');\n\n\n-- Format SQL:\nCREATE DATABASE IF NOT EXISTS `test` ENGINE = Replicated('/root/test_local', 'shard', 'replica');\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_dictionary_basic.sql",
    "content": "-- Origin SQL:\nCREATE DICTIONARY test.my_dict (\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'default'\n    password ''\n    db 'test'\n    table 'dict_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192);\n\n-- Format SQL:\nCREATE DICTIONARY test.my_dict (id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192);\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_dictionary_comprehensive.sql",
    "content": "-- Origin SQL:\nCREATE OR REPLACE DICTIONARY test.comprehensive_dict \nUUID '12345678-1234-1234-1234-123456789012'\nON CLUSTER production_cluster\n(\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'root'\n    password 'secret'\n    db 'test_db'\n    table 'dictionary_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192, max_insert_block_size = 1048576);\n\n-- Format SQL:\nCREATE OR REPLACE DICTIONARY test.comprehensive_dict UUID '12345678-1234-1234-1234-123456789012' ON CLUSTER production_cluster (id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192, max_insert_block_size=1048576);\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_dictionary_with_comment.sql",
    "content": "-- Origin SQL:\nCREATE DICTIONARY test.my_dict (\n    id UInt64,\n    name String DEFAULT '',\n    value Float64 EXPRESSION toFloat64OrZero(name),\n    parent_id UInt64 HIERARCHICAL,\n    is_active UInt8 INJECTIVE,\n    object_id UInt64 IS_OBJECT_ID\n)\nPRIMARY KEY id\nSOURCE(MYSQL(\n    host 'localhost'\n    port 3306\n    user 'default'\n    password ''\n    db 'test'\n    table 'dict_table'\n))\nLIFETIME(MIN 1000 MAX 2000)\nLAYOUT(HASHED())\nSETTINGS(max_block_size = 8192)\nCOMMENT 'This is a test dictionary with comment';\n\n\n-- Format SQL:\nCREATE DICTIONARY test.my_dict (id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192) COMMENT 'This is a test dictionary with comment';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_distributed_table.sql",
    "content": "-- Origin SQL:\ncreate table test.event_all\nON CLUSTER 'default_cluster'\nAS test.evnets_local\nENGINE = Distributed(\n    default_cluster,\n    test,\n    events_local,\n    rand()\n) SETTINGS fsync_after_insert=0;\n\n\n-- Format SQL:\nCREATE TABLE test.event_all ON CLUSTER 'default_cluster'  AS test.evnets_local ENGINE = Distributed(default_cluster, test, events_local, rand()) SETTINGS fsync_after_insert=0;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_function_simple.sql",
    "content": "-- Origin SQL:\nCREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b;\n\n-- Format SQL:\nCREATE FUNCTION linear_equation AS (x, k, b) -> k * x + b;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_live_view_basic.sql",
    "content": "-- Origin SQL:\nCREATE LIVE VIEW my_live_view\nWITH TIMEOUT 10 TO my_destination(id String)\nAS SELECT id FROM my_table;\n\n\n-- Format SQL:\nCREATE LIVE VIEW my_live_view WITH TIMEOUT 10 TO my_destination (id String) AS SELECT id FROM my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_materialized_view_basic.sql",
    "content": "-- Origin SQL:\nCREATE\nMATERIALIZED VIEW infra_bm.view_name \n    ON CLUSTER 'default_cluster' TO infra_bm.table_name\n(\n  `f1` DateTime64(3), \n  `f2` String, \n  `f3` String, \n  `f4` String, \n  `f5` String, \n  `f6` Int64\n) AS\nSELECT f1,\n       f2,\n       visitParamExtractString(properties, 'f3')   AS f3,\n       visitParamExtractString(properties, 'f4')      AS f4,\n       visitParamExtractString(properties, 'f5')    AS f5,\n    visitParamExtractInt(properties, 'f6') AS f6\nFROM\n    infra_bm.table_name1\nWHERE\n    infra_bm.table_name1.event = 'test-event'\nCOMMENT 'Comment for table';\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name (`f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' COMMENT 'Comment for table';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_materialized_view_with_comment_before_as.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table\n(\n    `shop_id` UInt64,\n    `event_type` LowCardinality(String),\n    `created_at` DateTime64(9)\n)\nCOMMENT '{\"blueprint_hash\":\"abc123\",\"timestamp\":\"2026-04-08T12:00:00Z\"}'\nAS SELECT\n    shop_id,\n    event_type,\n    created_at\nFROM db.src_table;\n\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table (`shop_id` UInt64, `event_type` LowCardinality(String), `created_at` DateTime64(9)) AS SELECT shop_id, event_type, created_at FROM db.src_table COMMENT '{\"blueprint_hash\":\"abc123\",\"timestamp\":\"2026-04-08T12:00:00Z\"}';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_materialized_view_with_definer.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export\n(\n    `timestamp` DateTime64(9),\n    `field_1` String,\n    `field_2` String,\n)\nDEFINER = default SQL SECURITY DEFINER\nAS (SELECT\n    timestamp,\n    field_1,\n    field_2,\nFROM event_table\nWHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1)))\nCOMMENT 'Test comment'\n\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export (`timestamp` DateTime64(9), `field_1` String, `field_2` String) DEFINER = default SQL SECURITY DEFINER AS (SELECT timestamp, field_1, field_2, FROM AS event_table WHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1))) COMMENT 'Test comment';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_materialized_view_with_empty_table_schema.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW test.t0 on cluster default_cluster\nENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}')\nPARTITION BY toYYYYMM(f0)\nORDER BY (f0)\nPOPULATE AS\nselect f0,f1,f2,coalesce(f0,f1) as f333\nfrom\n    (select\n         f0,f1,f2,\n         ROW_NUMBER() over(partition by f0 order by coalesce(f1,f2)) as rn\n     from test.t\n     where f3 in ('foo', 'bar', 'test')\n       and env ='test'\n    ) as tmp\nwhere rn = 1;\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW test.t0 ON CLUSTER default_cluster ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}') ORDER BY (f0) PARTITION BY toYYYYMM(f0) POPULATE AS SELECT f0, f1, f2, coalesce(f0, f1) AS f333 FROM (SELECT f0, f1, f2, ROW_NUMBER() OVER (PARTITION BY f0 ORDER BY coalesce(f1, f2)) AS rn FROM test.t WHERE f3 IN ('foo', 'bar', 'test') AND env = 'test') AS tmp WHERE rn = 1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_materialized_view_with_gcs.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW database_name.view_name\n        REFRESH EVERY 5 MINUTE TO database_name.table_name AS\n        SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/');\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW database_name.view_name REFRESH EVERY 5 MINUTE TO database_name.table_name AS SELECT * FROM gcs(gcs_creds, url='https://storage.googleapis.com/some-bucket/some-path/');\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_materialized_view_with_refresh.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW fresh_mv\nREFRESH EVERY 1 HOUR OFFSET 10 MINUTE\nRANDOMIZE FOR 1 SECOND\nDEPENDS ON  table_v5\nSETTINGS\n    randomize_for = 1,\n    randomize_offset = 10,\n    randomize_period = 1\nAPPEND TO target_table_name\nEMPTY\nAS SELECT\n    `field_1`,\n    `field_2`,\n    `field_3`,\nFROM table_v5\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE RANDOMIZE FOR 1 SECOND DEPENDS ON table_v5 SETTINGS randomize_for=1, randomize_offset=10, randomize_period=1 APPEND TO target_table_name EMPTY AS SELECT `field_1`, `field_2`, `field_3`, FROM AS table_v5;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_mv_with_not_op.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW infra_bm.view_name\n    ON CLUSTER 'default_cluster' TO infra_bm.table_name\n(\n  `f1` DateTime64(3),\n  `f2` String,\n  `f3` String,\n  `f4` String,\n  `f5` String,\n  `f6` Int64\n) AS\nSELECT f1,\n       f2,\n       visitParamExtractString(properties, 'f3') AS f3,\n       visitParamExtractString(properties, 'f4') AS f4,\n       visitParamExtractString(properties, 'f5') AS f5,\n       visitParamExtractInt(properties, 'f6') AS f6\nFROM infra_bm.table_name1\nWHERE infra_bm.table_name1.event = 'test-event' AND\n    NOT isZeroOrNull(f2) AND f6-2 > 0\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name (`f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' AND NOT isZeroOrNull(f2) AND f6 - 2 > 0;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_mv_with_order_by.sql",
    "content": "-- Origin SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nORDER BY (id)\nAS\nSELECT * FROM test_table;\n\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv\nENGINE = ReplacingMergeTree()\nPRIMARY KEY (id)\nAS\nSELECT * FROM test_table;\n\n-- Format SQL:\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() ORDER BY (id) PRIMARY KEY (id) AS SELECT * FROM test_table;\nCREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) AS SELECT * FROM test_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_named_collection_basic.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config\nAS url = 'http://local-minio:9000/*',\naccess_key_id = 'minioadmin',\nsecret_access_key = 'minioadmin';\n\n\n-- Format SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_named_collection_simple.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION my_collection\nAS key1 = 'value1',\nkey2 = 'value2';\n\n\n-- Format SQL:\nCREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_named_collection_with_cluster.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster\nAS key1 = 'value1' OVERRIDABLE,\nkey2 = 'value2' NOT OVERRIDABLE,\nkey3 = 'value3';\n\n\n-- Format SQL:\nCREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_named_collection_with_overridable.sql",
    "content": "-- Origin SQL:\nCREATE NAMED COLLECTION test_collection\nAS url = 'http://example.com' OVERRIDABLE,\naccess_key = 'key123' NOT OVERRIDABLE,\nsecret_key = 'secret456';\n\n\n-- Format SQL:\nCREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_or_replace.sql",
    "content": "-- Origin SQL:\n-- It's a short link events table\n/**\n    * @name Short link events\n    * @description It's a short link events table\n */\nCREATE OR REPLACE TABLE IF NOT EXISTS test.events_local (\n    f0 String,\n    f1 String CODEC(ZSTD(1)),\n    f2 VARCHAR(255),\n) ENGINE = MergeTree\nPRIMARY KEY (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f1)\nTTL f1 + INTERVAL 6 MONTH\nORDER BY (f1,f2)\nCOMMENT 'Comment for table';\n\nCREATE OR REPLACE VIEW IF NOT EXISTS my_view(col1 String, col2 String)\nAS\nSELECT\n    id,\n    name\nFROM\n    my_table;\n\nCREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y;\n\n-- Format SQL:\nCREATE OR REPLACE TABLE IF NOT EXISTS test.events_local (f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255)) ENGINE = MergeTree ORDER BY (f1, f2) PARTITION BY toYYYYMMDD(f1) PRIMARY KEY (f0, f1, f2) TTL f1 + INTERVAL 6 MONTH COMMENT 'Comment for table';\nCREATE OR REPLACE VIEW IF NOT EXISTS my_view (col1 String, col2 String) AS SELECT id, name FROM my_table;\nCREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_role.sql",
    "content": "-- Origin SQL:\n-- Tags: no-parallel\n\nCREATE ROLE r1_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2;\nCREATE ROLE r1_01293 SETTINGS NONE;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nCREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nCREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nCREATE ROLE r6_01293 SETTINGS max_memory_usage CONST;\nCREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nCREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nCREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 SETTINGS readonly=1;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nCREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nCREATE ROLE r5_01293 SETTINGS NONE;\nCREATE ROLE r1_01293@'%';\nCREATE ROLE r2_01293@'%.myhost.com';\n\n-- Format SQL:\nCREATE ROLE r1_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293;\nCREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2;\nCREATE ROLE r1_01293 SETTINGS NONE;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000;\nCREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;\nCREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;\nCREATE ROLE r6_01293 SETTINGS max_memory_usage CONST;\nCREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;\nCREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;\nCREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;\nCREATE ROLE r1_01293, r2_01293;\nCREATE ROLE r1_01293 SETTINGS readonly=1;\nCREATE ROLE r2_01293 SETTINGS PROFILE 'default';\nCREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;\nCREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;\nCREATE ROLE r5_01293 SETTINGS NONE;\nCREATE ROLE r1_01293@'%';\nCREATE ROLE r2_01293@'%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_as_remote_function.sql",
    "content": "-- Origin SQL:\n-- CREATE TABLE with columns AS table function (remoteSecure)\nCREATE TABLE test_remote\n(\n    id UInt64,\n    name String,\n    value Int32\n)\nAS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password');\n\n-- Simpler test case with remote()\nCREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table');\n\n\n-- Format SQL:\nCREATE TABLE test_remote (id UInt64, name String, value Int32) AS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password');\nCREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table');\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_basic.sql",
    "content": "-- Origin SQL:\n-- It's a short link events table\n/**\n    * @name Short link events\n    * @description It's a short link events table\n */\nCREATE TABLE IF NOT EXISTS test.events_local (\n    f0 String,\n    f1 String CODEC(ZSTD(1)),\n    f2 VARCHAR(255),\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Nested (\n        f70 UInt32,\n        f71 UInt32,\n        f72 DateTime,\n        f73 Int64,\n        f74 Int64,\n        f75 String\n    ),\n    f8 Datetime DEFAULT now(),\n    f9 String MATERIALIZED toString(f7['f70']),\n    f10 String ALIAS f11,\n    f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello'),\n) ENGINE = MergeTree\nPRIMARY KEY (f0, f1, f2)\nPARTITION BY toYYYYMMDD(f3)\nTTL f3 + INTERVAL 6 MONTH\nORDER BY (f1,f2,f3)\nCOMMENT 'Comment for table';\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test.events_local (f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Nested(f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String), f8 Datetime DEFAULT now(), f9 String MATERIALIZED toString(f7['f70']), f10 String ALIAS f11, f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c,  SKIP REGEXP 'hello')) ENGINE = MergeTree ORDER BY (f1, f2, f3) PARTITION BY toYYYYMMDD(f3) PRIMARY KEY (f0, f1, f2) TTL f3 + INTERVAL 6 MONTH COMMENT 'Comment for table';\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_codec_no_args.sql",
    "content": "-- Origin SQL:\nCREATE TABLE shark_attacks (\n    timestamp DateTime CODEC(DoubleDelta),\n);\n\n-- Format SQL:\nCREATE TABLE shark_attacks (timestamp DateTime CODEC(DoubleDelta));\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_json_typehints.sql",
    "content": "-- Origin SQL:\nCREATE TABLE t (\n    j JSON(message String, a.b UInt64, max_dynamic_paths=0, SKIP x, SKIP REGEXP 're')\n) ENGINE = MergeTree\nORDER BY tuple();\n\n\n\n\n-- Format SQL:\nCREATE TABLE t (j JSON(max_dynamic_paths=0, message String, a.b UInt64, SKIP x,  SKIP REGEXP 're')) ENGINE = MergeTree ORDER BY tuple();\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_codec_delta.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test_local\n(\n `id` UInt64 CODEC(Delta, ZSTD(1)),\n `api_id` UInt64 CODEC(ZSTD(1)),\n `app_id` UInt64 CODEC(Delta(9), ZSTD(1)),\n `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)),\n `guage` Float64 CODEC(Gorilla, LZ4),\n `value` UInt64 CODEC(T64, LZ4),\n `timestamp` DateTime64(9) CODEC(ZSTD(1)),\n INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nPARTITION BY toStartOfHour(`timestamp`)\nORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test_local (`id` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `app_id` UInt64 CODEC(Delta(9), ZSTD(1)), `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)), `guage` Float64 CODEC(Gorilla, LZ4), `value` UInt64 CODEC(T64, LZ4), `timestamp` DateTime64(9) CODEC(ZSTD(1)), INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) PARTITION BY toStartOfHour(`timestamp`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_enum_fields.sql",
    "content": "-- Origin SQL:\nCREATE TABLE t0 on cluster default_cluster\n(\n    `method` Enum8('GET'=1 , 'POST'=2, 'HEAD'=3, 'PUT'=4,'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)),\n    `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD)\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nPARTITION BY toDate(timestamp)\nORDER BY (method,timestamp)\nTTL toDate(timestamp) + toIntervalDay(3)\nSETTINGS index_granularity = 8192;\n\n-- Format SQL:\nCREATE TABLE t0 ON CLUSTER default_cluster (`method` Enum8('GET'=1, 'POST'=2, 'HEAD'=3, 'PUT'=4, 'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)), `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD)) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (method, timestamp) PARTITION BY toDate(timestamp) TTL toDate(timestamp) + toIntervalDay(3) SETTINGS index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_index.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test_local\n(\n `common.id` String CODEC(ZSTD(1)),\n `id` UInt64 CODEC(Delta, ZSTD(1)),\n `idx` UInt64 CODEC(Delta, ZSTD(1)),\n `api_id` UInt64 CODEC(ZSTD(1)),\n `arr` Array(Int64),\n `content` String CODEC(ZSTD(1)),\n `output` String,\n INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1,\n INDEX id_idx id TYPE minmax GRANULARITY 10,\n INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1,\n INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2,\n INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3,\n INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1,\n INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2\n)\nENGINE = ReplicatedMergeTree('/root/test_local', '{replica}')\nPARTITION BY toStartOfHour(`timestamp`)\nORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`)\nTTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY\nSETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test_local (`common.id` String CODEC(ZSTD(1)), `id` UInt64 CODEC(Delta, ZSTD(1)), `idx` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `arr` Array(Int64), `content` String CODEC(ZSTD(1)), `output` String, INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1, INDEX id_idx id TYPE minmax GRANULARITY 10, INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1, INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2, INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3, INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1, INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) PARTITION BY toStartOfHour(`timestamp`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_keyword_partition_by.sql",
    "content": "-- Origin SQL:\nCREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' (\n    `date` Date,\n    `f1` String,\n    `f2` String,\n    `f3` UInt64\n    ) ENGINE = ReplacingMergeTree\n    PARTITION BY date\n    ORDER BY (f1, f2)\n    SETTINGS index_granularity = 8192;\n\n-- Format SQL:\nCREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' (`date` Date, `f1` String, `f2` String, `f3` UInt64) ENGINE = ReplacingMergeTree ORDER BY (f1, f2) PARTITION BY date SETTINGS index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_null_engine.sql",
    "content": "-- Origin SQL:\nCREATE TABLE logs.t0 on cluster default\n(\n    `trace_id` String CODEC(ZSTD(1)),\n    INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64\n) ENGINE = Null();\n\n-- Format SQL:\nCREATE TABLE logs.t0 ON CLUSTER default (`trace_id` String CODEC(ZSTD(1)), INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64) ENGINE = Null();\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_nullable.sql",
    "content": "-- Origin SQL:\nCREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5`\n    UUID '27673372-7973-44f5-a767-33727973c4f5' (\n    `f0` String,\n    `f1` String,\n    `f2` LowCardinality(String),\n    `f3` LowCardinality(String),\n    `f4` DateTime64(3),\n    `f5` Nullable(DateTime64(3)),\n    `succeed_at` Nullable(DateTime64(3))\n) ENGINE = MergeTree\nPARTITION BY xxHash32(tag_id) % 20\nORDER BY label_id\nSETTINGS index_granularity = 8192;\n\n\n-- Format SQL:\nCREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5' (`f0` String, `f1` String, `f2` LowCardinality(String), `f3` LowCardinality(String), `f4` DateTime64(3), `f5` Nullable(DateTime64(3)), `succeed_at` Nullable(DateTime64(3))) ENGINE = MergeTree ORDER BY label_id PARTITION BY xxHash32(tag_id) % 20 SETTINGS index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_on_clsuter.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now()) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_projection.sql",
    "content": "-- Origin SQL:\nCREATE TABLE events\n(\n    `event_time` DateTime,\n    `event_id` UInt64,\n    `user_id` UInt64,\n    `huge_string` String,\n    PROJECTION order_by_user_id\n    (\n        SELECT\n            _part_offset\n        ORDER BY user_id\n    )\n)\nENGINE = MergeTree()\nORDER BY (event_id); \n\n-- Format SQL:\nCREATE TABLE events (`event_time` DateTime, `event_id` UInt64, `user_id` UInt64, `huge_string` String, PROJECTION order_by_user_id (SELECT _part_offset ORDER BY user_id)) ENGINE = MergeTree() ORDER BY (event_id);\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_projection_group_by_only.sql",
    "content": "-- Origin SQL:\nCREATE TABLE events\n(\n    `event_time` DateTime,\n    `event_type` String,\n    `user_id` UInt64,\n    `value` Float64,\n    PROJECTION hourly_aggregates\n    (\n        SELECT\n            toStartOfHour(event_time) AS hour,\n            event_type,\n            count() AS event_count,\n            sum(value) AS total_value\n        GROUP BY hour, event_type\n    )\n)\nENGINE = MergeTree()\nORDER BY (event_time, event_type);\n\n\n-- Format SQL:\nCREATE TABLE events (`event_time` DateTime, `event_type` String, `user_id` UInt64, `value` Float64, PROJECTION hourly_aggregates (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY hour, event_type)) ENGINE = MergeTree() ORDER BY (event_time, event_type);\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_qbit.sql",
    "content": "-- Origin SQL:\nCREATE TABLE test.qbit_example (\n    id UInt32,\n    vec QBit(Float32, 8)\n) ENGINE = Memory;\n\n\n-- Format SQL:\nCREATE TABLE test.qbit_example (id UInt32, vec QBit(Float32, 8)) ENGINE = Memory;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_sample_by.sql",
    "content": "-- Origin SQL:\nCREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e'\n(\n    `f0` DateTime,\n    `f1` UInt32,\n    `f3` UInt32\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}')\nPARTITION BY toYYYYMM(timestamp)\nORDER BY (contractid, toDate(timestamp), userid)\nSAMPLE BY userid\nSETTINGS index_granularity = 8192;\n\n-- Format SQL:\nCREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e' (`f0` DateTime, `f1` UInt32, `f3` UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}') ORDER BY (contractid, toDate(timestamp), userid) PARTITION BY toYYYYMM(timestamp) SAMPLE BY userid SETTINGS index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_ttl_policy.sql",
    "content": "-- Origin SQL:\nCREATE TABLE tab\n(\n    d DateTime,\n    a Int\n)\n    ENGINE = MergeTree\nPARTITION BY toYYYYMM(d)\nORDER BY d\nTTL d + INTERVAL 1 MONTH DELETE,\n    d + INTERVAL 1 WEEK TO VOLUME 'aaa',\n    d + INTERVAL 2 WEEK TO DISK 'bbb';\n\n\nCREATE TABLE table_with_where\n(\n    d DateTime,\n    a Int\n)\n    ENGINE = MergeTree\nPARTITION BY toYYYYMM(d)\nORDER BY d\nTTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1;\n\nCREATE TABLE table_for_recompression\n(\n    d DateTime,\n    key UInt64,\n    value String\n) ENGINE MergeTree()\nORDER BY tuple()\nPARTITION BY key\nTTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10))\nSETTINGS min_rows_for_wide_part = 0, min_bytes_for_wide_part = 0, allow_experimental_replacing_merge_with_cleanup = true;\n\n\n-- Format SQL:\nCREATE TABLE tab (d DateTime, a Int) ENGINE = MergeTree ORDER BY d PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb';\nCREATE TABLE table_with_where (d DateTime, a Int) ENGINE = MergeTree ORDER BY d PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1;\nCREATE TABLE table_for_recompression (d DateTime, key UInt64, value String) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY key TTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10)) SETTINGS min_rows_for_wide_part=0, min_bytes_for_wide_part=0, allow_experimental_replacing_merge_with_cleanup=true;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_tuple_fields.sql",
    "content": "-- Origin SQL:\nCREATE TABLE t0 on cluster default_cluster\n(\n    `tup0` Tuple(),\n    `tup1` Tuple(String, Int64),\n    `tup2` Tuple(String, Tuple(String, String)),\n    `tup3` Tuple(a String, cd Tuple(c String, d String))\n)\nENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')\nORDER BY (tup1, tup2, tup3)\nSETTINGS index_granularity = 8192;\n\n\n-- Format SQL:\nCREATE TABLE t0 ON CLUSTER default_cluster (`tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String))) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity=8192;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_table_with_uuid.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' (\n    f0 String,\n    f1 String,\n    f2 String,\n    f3 Datetime,\n    f4 Datetime,\n    f5 Map(String,String),\n    f6 String,\n    f7 Datetime DEFAULT now()\n) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}')\nTTL f3 + INTERVAL 6 MONTH\nPARTITION BY toYYYYMMDD(f3)\nORDER BY (f0,f1,f2);\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' (f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now()) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_user.sql",
    "content": "-- Origin SQL:\n-- Basic CREATE USER tests\n\nCREATE USER user1;\nCREATE USER IF NOT EXISTS user2;\nCREATE USER OR REPLACE user3;\nCREATE USER user4, user5;\n\n-- CREATE USER with authentication\nCREATE USER user6 NOT IDENTIFIED;\nCREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123';\nCREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123';\nCREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server';\nCREATE USER user10 IDENTIFIED WITH kerberos;\nCREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM';\n\n-- CREATE USER with VALID UNTIL\nCREATE USER user33 VALID UNTIL '2026-12-12 00:00:00';\nCREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15';\nCREATE USER user35 VALID UNTIL 'infinity';\n\n-- CREATE USER with host restrictions\nCREATE USER user12 HOST LOCAL;\nCREATE USER user13 HOST ANY;\nCREATE USER user14 HOST NONE;\nCREATE USER user15 HOST NAME 'localhost';\nCREATE USER user16 HOST REGEXP '.*\\.example\\.com';\nCREATE USER user17 HOST IP '192.168.1.1';\nCREATE USER user18 HOST LIKE 'test%';\n\n-- CREATE USER with default roles\nCREATE USER user19 DEFAULT ROLE role1;\nCREATE USER user20 DEFAULT ROLE role1, role2;\nCREATE USER user21 DEFAULT ROLE NONE;\n\n-- CREATE USER with default database\nCREATE USER user22 DEFAULT DATABASE test_db;\nCREATE USER user23 DEFAULT DATABASE NONE;\n\n-- CREATE USER with grantees\nCREATE USER user24 GRANTEES user1;\nCREATE USER user25 GRANTEES user1, user2;\nCREATE USER user26 GRANTEES ANY;\nCREATE USER user27 GRANTEES NONE;\nCREATE USER user28 GRANTEES user1, user2 EXCEPT user3;\n\n-- CREATE USER with settings\nCREATE USER user29 SETTINGS max_memory_usage=5000000;\nCREATE USER user30 SETTINGS PROFILE 'default';\nCREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000;\n\n-- Complex CREATE USER with multiple clauses\nCREATE USER user32\n    IDENTIFIED WITH plaintext_password BY 'password'\n    VALID UNTIL '2025-12-31'\n    HOST NAME 'localhost'\n    DEFAULT ROLE role1, role2\n    DEFAULT DATABASE test_db\n    GRANTEES user1, user2 EXCEPT user3\n    SETTINGS max_memory_usage=5000000, readonly=1;\n\n-- Format SQL:\nCREATE USER user1;\nCREATE USER IF NOT EXISTS user2;\nCREATE USER OR REPLACE user3;\nCREATE USER user4, user5;\nCREATE USER user6 NOT IDENTIFIED;\nCREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123';\nCREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123';\nCREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server';\nCREATE USER user10 IDENTIFIED WITH kerberos;\nCREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM';\nCREATE USER user33 VALID UNTIL '2026-12-12 00:00:00';\nCREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15';\nCREATE USER user35 VALID UNTIL 'infinity';\nCREATE USER user12 HOST LOCAL;\nCREATE USER user13 HOST ANY;\nCREATE USER user14 HOST NONE;\nCREATE USER user15 HOST NAME 'localhost';\nCREATE USER user16 HOST REGEXP '.*\\.example\\.com';\nCREATE USER user17 HOST IP '192.168.1.1';\nCREATE USER user18 HOST LIKE 'test%';\nCREATE USER user19 DEFAULT ROLE role1;\nCREATE USER user20 DEFAULT ROLE role1, role2;\nCREATE USER user21 DEFAULT ROLE NONE;\nCREATE USER user22 DEFAULT DATABASE test_db;\nCREATE USER user23 DEFAULT DATABASE NONE;\nCREATE USER user24 GRANTEES user1;\nCREATE USER user25 GRANTEES user1, user2;\nCREATE USER user26 GRANTEES ANY;\nCREATE USER user27 GRANTEES NONE;\nCREATE USER user28 GRANTEES user1, user2 EXCEPT user3;\nCREATE USER user29 SETTINGS max_memory_usage=5000000;\nCREATE USER user30 SETTINGS PROFILE 'default';\nCREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000;\nCREATE USER user32 IDENTIFIED WITH plaintext_password BY 'password' VALID UNTIL '2025-12-31' HOST NAME 'localhost' DEFAULT ROLE role1, role2 DEFAULT DATABASE test_db GRANTEES user1, user2 EXCEPT user3 SETTINGS max_memory_usage=5000000, readonly=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_view_basic.sql",
    "content": "-- Origin SQL:\nCREATE VIEW IF NOT EXISTS my_view(col1 String, col2 String)\nAS\nSELECT\n    id,\n    name\nFROM\n    my_table;\n\n-- Format SQL:\nCREATE VIEW IF NOT EXISTS my_view (col1 String, col2 String) AS SELECT id, name FROM my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_view_on_cluster_with_uuid.sql",
    "content": "-- Origin SQL:\nCREATE VIEW IF NOT EXISTS cluster_name.my_view\n        UUID '3493e374-e2bb-481b-b493-e374e2bb981b'\n        ON CLUSTER 'my_cluster'\nAS (\n    SELECT\n    column1,\n    column2\n    FROM\n    my_other_table\n);\n\n-- Format SQL:\nCREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS (SELECT column1, column2 FROM my_other_table);\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_view_with_comment.sql",
    "content": "-- Origin SQL:\nCREATE VIEW IF NOT EXISTS db.my_view\n(\n    `id` Int64,\n    `name` String\n)\nCOMMENT '{\"blueprint_hash\":\"abc123\"}'\nAS SELECT\n    id,\n    name\nFROM db.my_table;\n\n\n-- Format SQL:\nCREATE VIEW IF NOT EXISTS db.my_view (`id` Int64, `name` String) COMMENT '{\"blueprint_hash\":\"abc123\"}' AS SELECT id, name FROM db.my_table;\n"
  },
  {
    "path": "parser/testdata/ddl/format/create_with_time_zone.sql",
    "content": "-- Origin SQL:\nCREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster\n(\n    `f0` Array(Tuple(\n        f00 DateTime64(9, 'UTC'),\n        f01 String,\n        f02 Map(String, String),\n        f03 Map(String, Float64),\n        f04 Map(String, BOOL))) CODEC(ZSTD(1)\n    ),\n    `f1` UInt64 CODEC(Delta(8), LZ4),\n    `f2` FixedString(16) CODEC(LZ4),\n    `f3` FixedString(8) CODEC(LZ4),\n    `f4` FixedString(8) CODEC(LZ4),\n    `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4),\n    `f6` UInt64 CODEC(Delta(8), LZ4),\n    `f7` LowCardinality(String) CODEC(ZSTD(1)),\n    `f8` String CODEC(ZSTD(1)),\n    `f9` LowCardinality(String) CODEC(ZSTD(1)),\n    `f10` String CODEC(ZSTD(1)),\n    `f11` LowCardinality(String) CODEC(ZSTD(1)),\n    `f12` LowCardinality(String) CODEC(ZSTD(1)),\n    `f13` String CODEC(ZSTD(1)),\n    `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n    `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n    `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)),\n    `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)),\n    `f18` Array(Tuple(\n        f180 FixedString(16),\n        f181 FixedString(8),\n        f182 String,\n        f183 Map(String, String))) CODEC(ZSTD(1)),\n        `f184` String CODEC(ZSTD(1)),\n        `f185` String CODEC(ZSTD(1)),\n        `f186` String CODEC(ZSTD(1)),\n        `f187` UInt32 CODEC(ZSTD(1)),\n        `f188` DATETIME DEFAULT now(),\n        INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1,\n        INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1,\n        INDEX idx_f2 f2 TYPE minmax GRANULARITY 1,\n        INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4,\n        INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1,\n        INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4\n    )\n    ENGINE = MergeTree\n    PARTITION BY toDate(timestamp)\n    ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp))\n    TTL toDate(timestamp) + toIntervalDay(15)\n    SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1\n\n-- Format SQL:\nCREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster (`f0` Array(Tuple(f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1)), `f1` UInt64 CODEC(Delta(8), LZ4), `f2` FixedString(16) CODEC(LZ4), `f3` FixedString(8) CODEC(LZ4), `f4` FixedString(8) CODEC(LZ4), `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4), `f6` UInt64 CODEC(Delta(8), LZ4), `f7` LowCardinality(String) CODEC(ZSTD(1)), `f8` String CODEC(ZSTD(1)), `f9` LowCardinality(String) CODEC(ZSTD(1)), `f10` String CODEC(ZSTD(1)), `f11` LowCardinality(String) CODEC(ZSTD(1)), `f12` LowCardinality(String) CODEC(ZSTD(1)), `f13` String CODEC(ZSTD(1)), `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)), `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)), `f18` Array(Tuple(f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)), `f184` String CODEC(ZSTD(1)), `f185` String CODEC(ZSTD(1)), `f186` String CODEC(ZSTD(1)), `f187` UInt32 CODEC(ZSTD(1)), `f188` DATETIME DEFAULT now(), INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f2 f2 TYPE minmax GRANULARITY 1, INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4, INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1, INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4) ENGINE = MergeTree ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp)) PARTITION BY toDate(timestamp) TTL toDate(timestamp) + toIntervalDay(15) SETTINGS index_granularity=8192, ttl_only_drop_parts=1;\n"
  },
  {
    "path": "parser/testdata/ddl/format/desc_table_with_table_keyword.sql",
    "content": "-- Origin SQL:\nDESC TABLE mytable\n\n-- Format SQL:\nDESCRIBE TABLE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/desc_table_without_table_keyword.sql",
    "content": "-- Origin SQL:\nDESC mytable\n\n-- Format SQL:\nDESCRIBE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/describe_table_with_table_keyword.sql",
    "content": "-- Origin SQL:\nDESCRIBE TABLE mytable\n\n-- Format SQL:\nDESCRIBE TABLE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/describe_table_without_table_keyword.sql",
    "content": "-- Origin SQL:\nDESCRIBE mytable\n\n-- Format SQL:\nDESCRIBE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/drop_database.sql",
    "content": "-- Origin SQL:\nDROP DATABASE IF EXISTS datbase_name;\n\n\n-- Format SQL:\nDROP DATABASE IF EXISTS datbase_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/drop_role.sql",
    "content": "-- Origin SQL:\nDROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293;\nDROP ROLE IF EXISTS r2_01293_renamed;\nDROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com';\n\n\n-- Format SQL:\nDROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293;\nDROP ROLE IF EXISTS r2_01293_renamed;\nDROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com';\n"
  },
  {
    "path": "parser/testdata/ddl/format/drop_table_basic.sql",
    "content": "-- Origin SQL:\nDROP TABLE IF EXISTS test.table_name;\n\n\n-- Format SQL:\nDROP TABLE IF EXISTS test.table_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/drop_table_with_no_delay.sql",
    "content": "-- Origin SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY;\n\n\n-- Format SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY;\n"
  },
  {
    "path": "parser/testdata/ddl/format/drop_table_with_on_clsuter.sql",
    "content": "-- Origin SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n\n\n-- Format SQL:\nDROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/format/grant_privilege.sql",
    "content": "-- Origin SQL:\nGRANT SELECT(x,y) ON db.table TO john;\nGRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION;\nGRANT SELECT(x,y) ON db.* TO john;\nGRANT SELECT(x,y) ON *.table TO john;\nGRANT SELECT(x,y) ON *.* TO john;\nGRANT SELECT(x,y) ON *.table TO CURRENT_USER;\nGRANT SELECT(x,y) ON *.table TO CURRENT_USER,john,mary;\nGRANT ALL ON *.* TO admin_role WITH GRANT OPTION;\nGRANT SELECT,INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT(x, y, z),INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT, dictGet ON *.*  TO select_all_role;\nGRANT ADMIN OPTION ON *.*  TO select_all_role;\n\n\n\n-- Format SQL:\nGRANT SELECT(x, y) ON db.table TO john;\nGRANT SELECT(x, y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION;\nGRANT SELECT(x, y) ON db.* TO john;\nGRANT SELECT(x, y) ON *.table TO john;\nGRANT SELECT(x, y) ON *.* TO john;\nGRANT SELECT(x, y) ON *.table TO CURRENT_USER;\nGRANT SELECT(x, y) ON *.table TO CURRENT_USER, john, mary;\nGRANT ALL ON *.* TO admin_role WITH GRANT OPTION;\nGRANT SELECT, INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT(x, y, z), INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT, dictGet ON *.* TO select_all_role;\nGRANT ADMIN OPTION ON *.* TO select_all_role;\n"
  },
  {
    "path": "parser/testdata/ddl/format/optimize.sql",
    "content": "-- Origin SQL:\nOPTIMIZE TABLE table DEDUPLICATE; -- all columns\nOPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns\nOPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY);\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex');\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY);\n\n-- Format SQL:\nOPTIMIZE TABLE table DEDUPLICATE;\nOPTIMIZE TABLE table DEDUPLICATE BY *;\nOPTIMIZE TABLE table DEDUPLICATE BY colX, colY, colZ;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY);\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex');\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY);\n"
  },
  {
    "path": "parser/testdata/ddl/format/rename.sql",
    "content": "-- Origin SQL:\n-- rename table\nRENAME TABLE t1 TO t11;\nRENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME TABLE t1 TO t11, t2 TO t22;\nRENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n-- rename dictionary   \nRENAME DICTIONARY t1 TO t11;\nRENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11, t2 TO t22;\nRENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n-- rename database\nRENAME DATABASE t1 TO t11;\nRENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11, t2 TO t22;\nRENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n\n\n-- Format SQL:\nRENAME TABLE t1 TO t11;\nRENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME TABLE t1 TO t11, t2 TO t22;\nRENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11;\nRENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11, t2 TO t22;\nRENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11;\nRENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11, t2 TO t22;\nRENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_create_table.sql",
    "content": "-- Origin SQL:\nSHOW CREATE TABLE mytable\n\n-- Format SQL:\nSHOW CREATE TABLE mytable;\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES\n\n-- Format SQL:\nSHOW DATABASES;\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_comprehensive.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON\n\n-- Format SQL:\nSHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT 'JSON';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_format.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES FORMAT JSON\n\n-- Format SQL:\nSHOW DATABASES FORMAT 'JSON';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_format_string.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES FORMAT 'TabSeparated'\n\n-- Format SQL:\nSHOW DATABASES FORMAT 'TabSeparated';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_ilike.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES ILIKE 'Test%'\n\n-- Format SQL:\nSHOW DATABASES ILIKE 'Test%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_like.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES LIKE 'test%'\n\n-- Format SQL:\nSHOW DATABASES LIKE 'test%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_limit.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES LIMIT 10\n\n-- Format SQL:\nSHOW DATABASES LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_not_ilike.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES NOT ILIKE 'Temp%'\n\n-- Format SQL:\nSHOW DATABASES NOT ILIKE 'Temp%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_not_like.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES NOT LIKE 'temp%'\n\n-- Format SQL:\nSHOW DATABASES NOT LIKE 'temp%';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_databases_outfile.sql",
    "content": "-- Origin SQL:\nSHOW DATABASES INTO OUTFILE '/tmp/databases.txt'\n\n-- Format SQL:\nSHOW DATABASES INTO OUTFILE '/tmp/databases.txt';\n"
  },
  {
    "path": "parser/testdata/ddl/format/show_tables.sql",
    "content": "-- Origin SQL:\nSHOW TABLES\n\n-- Format SQL:\nSHOW TABLES;\n"
  },
  {
    "path": "parser/testdata/ddl/format/systems.sql",
    "content": "-- Origin SQL:\nSYSTEM FLUSH LOGS;\nSYSTEM DROP UNCOMPRESSED CACHE;\nSYSTEM DROP FILESYSTEM CACHE;\n\n\n-- Format SQL:\nSYSTEM FLUSH LOGS;\nSYSTEM DROP UNCOMPRESSED CACHE;\nSYSTEM DROP FILESYSTEM CACHE;\n"
  },
  {
    "path": "parser/testdata/ddl/format/truncate_table_basic.sql",
    "content": "-- Origin SQL:\nTRUNCATE TABLE IF EXISTS test.table_name;\n\n\n-- Format SQL:\nTRUNCATE TABLE IF EXISTS test.table_name;\n"
  },
  {
    "path": "parser/testdata/ddl/format/truncate_temporary_table_on_clsuter.sql",
    "content": "-- Origin SQL:\nTRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n\n\n-- Format SQL:\nTRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/grant_privilege.sql",
    "content": "GRANT SELECT(x,y) ON db.table TO john;\nGRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION;\nGRANT SELECT(x,y) ON db.* TO john;\nGRANT SELECT(x,y) ON *.table TO john;\nGRANT SELECT(x,y) ON *.* TO john;\nGRANT SELECT(x,y) ON *.table TO CURRENT_USER;\nGRANT SELECT(x,y) ON *.table TO CURRENT_USER,john,mary;\nGRANT ALL ON *.* TO admin_role WITH GRANT OPTION;\nGRANT SELECT,INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT(x, y, z),INSERT ON database.table_1 TO table_1_select_role;\nGRANT SELECT, dictGet ON *.*  TO select_all_role;\nGRANT ADMIN OPTION ON *.*  TO select_all_role;\n\n"
  },
  {
    "path": "parser/testdata/ddl/optimize.sql",
    "content": "OPTIMIZE TABLE table DEDUPLICATE; -- all columns\nOPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns\nOPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY);\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex');\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX;\nOPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY);"
  },
  {
    "path": "parser/testdata/ddl/output/alter_role.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 22,\n    \"StatementEnd\": 41,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 33,\n            \"NameEnd\": 41\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 41\n      }\n    ],\n    \"Settings\": null\n  },\n  {\n    \"AlterPos\": 43,\n    \"StatementEnd\": 102,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 54,\n            \"NameEnd\": 62\n          },\n          \"Scope\": null,\n          \"OnCluster\": {\n            \"OnPos\": 63,\n            \"Expr\": {\n              \"Name\": \"cluster_1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 74,\n              \"NameEnd\": 83\n            }\n          }\n        },\n        \"NewName\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 94,\n          \"NameEnd\": 102\n        },\n        \"StatementEnd\": 102\n      }\n    ],\n    \"Settings\": null\n  },\n  {\n    \"AlterPos\": 104,\n    \"StatementEnd\": 171,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 115,\n            \"NameEnd\": 123\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 134,\n          \"NameEnd\": 142\n        },\n        \"StatementEnd\": 142\n      },\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r3_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 144,\n            \"NameEnd\": 152\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": {\n          \"Name\": \"r4_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 163,\n          \"NameEnd\": 171\n        },\n        \"StatementEnd\": 171\n      }\n    ],\n    \"Settings\": null\n  },\n  {\n    \"AlterPos\": 173,\n    \"StatementEnd\": 206,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 184,\n            \"NameEnd\": 192\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 192\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [],\n        \"Modifier\": {\n          \"Name\": \"NONE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 202,\n          \"NameEnd\": 206\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 208,\n    \"StatementEnd\": 253,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r2_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 219,\n            \"NameEnd\": 227\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 227\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 237,\n              \"NameEnd\": 244\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 246,\n              \"LiteralEnd\": 253,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 256,\n    \"StatementEnd\": 309,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r3_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 267,\n            \"NameEnd\": 275\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 275\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 285,\n              \"NameEnd\": 301\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 302,\n              \"NumEnd\": 309,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 311,\n    \"StatementEnd\": 368,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r4_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 322,\n            \"NameEnd\": 330\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 330\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 340,\n              \"NameEnd\": 356\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MIN\",\n              \"QuoteType\": 1,\n              \"NamePos\": 357,\n              \"NameEnd\": 360\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 361,\n              \"NumEnd\": 368,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 370,\n    \"StatementEnd\": 427,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r5_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 381,\n            \"NameEnd\": 389\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 389\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 399,\n              \"NameEnd\": 415\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MAX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 416,\n              \"NameEnd\": 419\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 420,\n              \"NumEnd\": 427,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 429,\n    \"StatementEnd\": 480,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r6_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 440,\n            \"NameEnd\": 448\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 448\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 458,\n              \"NameEnd\": 474\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"CONST\",\n          \"QuoteType\": 1,\n          \"NamePos\": 475,\n          \"NameEnd\": 480\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 482,\n    \"StatementEnd\": 536,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r7_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 493,\n            \"NameEnd\": 501\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 501\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 511,\n              \"NameEnd\": 527\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"WRITABLE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 528,\n          \"NameEnd\": 536\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 538,\n    \"StatementEnd\": 621,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r8_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 549,\n            \"NameEnd\": 557\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 557\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 567,\n              \"NameEnd\": 583\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 584,\n              \"NumEnd\": 591,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MIN\",\n              \"QuoteType\": 1,\n              \"NamePos\": 592,\n              \"NameEnd\": 595\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 596,\n              \"NumEnd\": 603,\n              \"Literal\": \"4000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MAX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 604,\n              \"NameEnd\": 607\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 608,\n              \"NumEnd\": 615,\n              \"Literal\": \"6000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"CONST\",\n          \"QuoteType\": 1,\n          \"NamePos\": 616,\n          \"NameEnd\": 621\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 623,\n    \"StatementEnd\": 704,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r9_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 634,\n            \"NameEnd\": 642\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 642\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 652,\n              \"NameEnd\": 659\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 661,\n              \"LiteralEnd\": 668,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 671,\n              \"NameEnd\": 687\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 688,\n              \"NumEnd\": 695,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"WRITABLE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 696,\n          \"NameEnd\": 704\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 706,\n    \"StatementEnd\": 735,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 717,\n            \"NameEnd\": 725\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 725\n      },\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r2_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 727,\n            \"NameEnd\": 735\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 735\n      }\n    ],\n    \"Settings\": null\n  },\n  {\n    \"AlterPos\": 737,\n    \"StatementEnd\": 776,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 748,\n            \"NameEnd\": 756\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 756\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"readonly\",\n              \"QuoteType\": 1,\n              \"NamePos\": 766,\n              \"NameEnd\": 774\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 775,\n              \"NumEnd\": 776,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 778,\n    \"StatementEnd\": 823,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r2_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 789,\n            \"NameEnd\": 797\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 797\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 807,\n              \"NameEnd\": 814\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 816,\n              \"LiteralEnd\": 823,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 826,\n    \"StatementEnd\": 912,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r3_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 837,\n            \"NameEnd\": 845\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 845\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 855,\n              \"NameEnd\": 871\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 872,\n              \"NumEnd\": 879,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MIN\",\n              \"QuoteType\": 1,\n              \"NamePos\": 880,\n              \"NameEnd\": 883\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 884,\n              \"NumEnd\": 891,\n              \"Literal\": \"4000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MAX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 892,\n              \"NameEnd\": 895\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 896,\n              \"NumEnd\": 903,\n              \"Literal\": \"6000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"WRITABLE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 904,\n          \"NameEnd\": 912\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 914,\n    \"StatementEnd\": 998,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r4_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 925,\n            \"NameEnd\": 933\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 933\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 943,\n              \"NameEnd\": 950\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 952,\n              \"LiteralEnd\": 959,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 962,\n              \"NameEnd\": 978\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 979,\n              \"NumEnd\": 986,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"readonly\",\n              \"QuoteType\": 1,\n              \"NamePos\": 988,\n              \"NameEnd\": 996\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 997,\n              \"NumEnd\": 998,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 1000,\n    \"StatementEnd\": 1033,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r5_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1011,\n            \"NameEnd\": 1019\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 1019\n      }\n    ],\n    \"Settings\": [\n      {\n        \"SettingPairs\": [],\n        \"Modifier\": {\n          \"Name\": \"NONE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1029,\n          \"NameEnd\": 1033\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 1035,\n    \"StatementEnd\": 1057,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r1_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1046,\n            \"NameEnd\": 1054\n          },\n          \"Scope\": {\n            \"LiteralPos\": 1056,\n            \"LiteralEnd\": 1057,\n            \"Literal\": \"%\"\n          },\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 1057\n      }\n    ],\n    \"Settings\": null\n  },\n  {\n    \"AlterPos\": 1060,\n    \"StatementEnd\": 1093,\n    \"IfExists\": false,\n    \"RoleRenamePairs\": [\n      {\n        \"RoleName\": {\n          \"Name\": {\n            \"Name\": \"r2_01293\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1071,\n            \"NameEnd\": 1079\n          },\n          \"Scope\": {\n            \"LiteralPos\": 1081,\n            \"LiteralEnd\": 1093,\n            \"Literal\": \"%.myhost.com\"\n          },\n          \"OnCluster\": null\n        },\n        \"NewName\": null,\n        \"StatementEnd\": 1093\n      }\n    ],\n    \"Settings\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_add_column.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 112,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 29\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 30,\n      \"Expr\": {\n        \"LiteralPos\": 42,\n        \"LiteralEnd\": 57,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 59,\n        \"StatementEnd\": 112,\n        \"Column\": {\n          \"NamePos\": 70,\n          \"ColumnEnd\": 79,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 70,\n              \"NameEnd\": 72\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 73,\n              \"NameEnd\": 79\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        \"IfNotExists\": false,\n        \"After\": {\n          \"Ident\": {\n            \"Name\": \"f0\",\n            \"QuoteType\": 1,\n            \"NamePos\": 86,\n            \"NameEnd\": 88\n          },\n          \"DotIdent\": null\n        },\n        \"Settings\": {\n          \"SettingsPos\": 89,\n          \"ListEnd\": 112,\n          \"Items\": [\n            {\n              \"SettingsPos\": 98,\n              \"Name\": {\n                \"Name\": \"alter_sync\",\n                \"QuoteType\": 1,\n                \"NamePos\": 98,\n                \"NameEnd\": 108\n              },\n              \"Expr\": {\n                \"NumPos\": 111,\n                \"NumEnd\": 112,\n                \"Literal\": \"2\",\n                \"Base\": 10\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_add_index.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 110,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 29\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 30,\n      \"Expr\": {\n        \"LiteralPos\": 42,\n        \"LiteralEnd\": 57,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 59,\n        \"StatementEnd\": 110,\n        \"Index\": {\n          \"IndexPos\": 63,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"my_index\",\n              \"QuoteType\": 1,\n              \"NamePos\": 69,\n              \"NameEnd\": 77\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"LeftParenPos\": 77,\n              \"RightParenPos\": 80,\n              \"Items\": {\n                \"ListPos\": 78,\n                \"ListEnd\": 80,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 78,\n                      \"NameEnd\": 80\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"Name\": {\n              \"Name\": \"minmax\",\n              \"QuoteType\": 1,\n              \"NamePos\": 87,\n              \"NameEnd\": 93\n            }\n          },\n          \"Granularity\": {\n            \"NumPos\": 106,\n            \"NumEnd\": 110,\n            \"Literal\": \"1024\",\n            \"Base\": 10\n          }\n        },\n        \"IfNotExists\": false,\n        \"After\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 112,\n    \"StatementEnd\": 226,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 124,\n        \"NameEnd\": 128\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 129,\n        \"NameEnd\": 141\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 142,\n      \"Expr\": {\n        \"LiteralPos\": 154,\n        \"LiteralEnd\": 169,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 171,\n        \"StatementEnd\": 226,\n        \"Index\": {\n          \"IndexPos\": 175,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"api_id_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 181,\n              \"NameEnd\": 191\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"api_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 192,\n              \"NameEnd\": 198\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 208,\n            \"RightParenPos\": 211,\n            \"Name\": {\n              \"Name\": \"set\",\n              \"QuoteType\": 1,\n              \"NamePos\": 204,\n              \"NameEnd\": 207\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 208,\n                \"NumEnd\": 211,\n                \"Literal\": \"100\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 225,\n            \"NumEnd\": 226,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        },\n        \"IfNotExists\": false,\n        \"After\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 228,\n    \"StatementEnd\": 346,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 240,\n        \"NameEnd\": 244\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 245,\n        \"NameEnd\": 257\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 258,\n      \"Expr\": {\n        \"LiteralPos\": 270,\n        \"LiteralEnd\": 285,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 287,\n        \"StatementEnd\": 346,\n        \"Index\": {\n          \"IndexPos\": 291,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"arr_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 297,\n              \"NameEnd\": 304\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"arr\",\n              \"QuoteType\": 1,\n              \"NamePos\": 305,\n              \"NameEnd\": 308\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 327,\n            \"RightParenPos\": 331,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 314,\n              \"NameEnd\": 326\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 327,\n                \"NumEnd\": 331,\n                \"Literal\": \"0.01\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 345,\n            \"NumEnd\": 346,\n            \"Literal\": \"3\",\n            \"Base\": 10\n          }\n        },\n        \"IfNotExists\": false,\n        \"After\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 348,\n    \"StatementEnd\": 479,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 360,\n        \"NameEnd\": 364\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 365,\n        \"NameEnd\": 377\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 378,\n      \"Expr\": {\n        \"LiteralPos\": 390,\n        \"LiteralEnd\": 405,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 407,\n        \"StatementEnd\": 479,\n        \"Index\": {\n          \"IndexPos\": 411,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"content_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 417,\n              \"NameEnd\": 428\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"content\",\n              \"QuoteType\": 1,\n              \"NamePos\": 429,\n              \"NameEnd\": 436\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 453,\n            \"RightParenPos\": 464,\n            \"Name\": {\n              \"Name\": \"tokenbf_v1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 442,\n              \"NameEnd\": 452\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 453,\n                \"NumEnd\": 458,\n                \"Literal\": \"30720\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 460,\n                \"NumEnd\": 461,\n                \"Literal\": \"2\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 463,\n                \"NumEnd\": 464,\n                \"Literal\": \"0\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 478,\n            \"NumEnd\": 479,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        \"IfNotExists\": false,\n        \"After\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 481,\n    \"StatementEnd\": 613,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 493,\n        \"NameEnd\": 497\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 498,\n        \"NameEnd\": 510\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 511,\n      \"Expr\": {\n        \"LiteralPos\": 523,\n        \"LiteralEnd\": 538,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 540,\n        \"StatementEnd\": 613,\n        \"Index\": {\n          \"IndexPos\": 544,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"output_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 550,\n              \"NameEnd\": 560\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"output\",\n              \"QuoteType\": 1,\n              \"NamePos\": 561,\n              \"NameEnd\": 567\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 584,\n            \"RightParenPos\": 598,\n            \"Name\": {\n              \"Name\": \"ngrambf_v1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 573,\n              \"NameEnd\": 583\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 584,\n                \"NumEnd\": 585,\n                \"Literal\": \"3\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 587,\n                \"NumEnd\": 592,\n                \"Literal\": \"10000\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 594,\n                \"NumEnd\": 595,\n                \"Literal\": \"2\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 597,\n                \"NumEnd\": 598,\n                \"Literal\": \"1\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 612,\n            \"NumEnd\": 613,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        },\n        \"IfNotExists\": false,\n        \"After\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_add_projection.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 140,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"visits_order\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 24\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 25,\n        \"StatementEnd\": 140,\n        \"IfNotExists\": true,\n        \"TableProjection\": {\n          \"IncludeProjectionKeyword\": false,\n          \"ProjectionPos\": 55,\n          \"Identifier\": {\n            \"Ident\": {\n              \"Name\": \"user_name_projection\",\n              \"QuoteType\": 1,\n              \"NamePos\": 55,\n              \"NameEnd\": 75\n            },\n            \"DotIdent\": null\n          },\n          \"Select\": {\n            \"LeftParenPos\": 76,\n            \"RightParenPos\": 123,\n            \"With\": null,\n            \"SelectColumns\": {\n              \"ListPos\": 84,\n              \"ListEnd\": 84,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"*\",\n                    \"QuoteType\": 0,\n                    \"NamePos\": 84,\n                    \"NameEnd\": 84\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"GroupBy\": {\n              \"GroupByPos\": 86,\n              \"GroupByEnd\": 105,\n              \"AggregateType\": \"\",\n              \"Expr\": {\n                \"ListPos\": 95,\n                \"ListEnd\": 104,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"user_name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 95,\n                      \"NameEnd\": 104\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"WithCube\": false,\n              \"WithRollup\": false,\n              \"WithTotals\": false\n            },\n            \"OrderBy\": {\n              \"OrderByPos\": 105,\n              \"Columns\": {\n                \"ListPos\": 114,\n                \"ListEnd\": 123,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"user_name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 114,\n                      \"NameEnd\": 123\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            }\n          }\n        },\n        \"After\": {\n          \"Ident\": {\n            \"Name\": \"a\",\n            \"QuoteType\": 1,\n            \"NamePos\": 131,\n            \"NameEnd\": 132\n          },\n          \"DotIdent\": {\n            \"Name\": \"user_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 133,\n            \"NameEnd\": 140\n          }\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_add_projection_group_by_only.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 182,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 18\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 19,\n        \"StatementEnd\": 182,\n        \"IfNotExists\": true,\n        \"TableProjection\": {\n          \"IncludeProjectionKeyword\": false,\n          \"ProjectionPos\": 48,\n          \"Identifier\": {\n            \"Ident\": {\n              \"Name\": \"hourly_stats\",\n              \"QuoteType\": 1,\n              \"NamePos\": 48,\n              \"NameEnd\": 60\n            },\n            \"DotIdent\": null\n          },\n          \"Select\": {\n            \"LeftParenPos\": 61,\n            \"RightParenPos\": 182,\n            \"With\": null,\n            \"SelectColumns\": {\n              \"ListPos\": 69,\n              \"ListEnd\": 156,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toStartOfHour\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 69,\n                      \"NameEnd\": 82\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 82,\n                      \"RightParenPos\": 93,\n                      \"Items\": {\n                        \"ListPos\": 83,\n                        \"ListEnd\": 93,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": \"event_time\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 83,\n                              \"NameEnd\": 93\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"hour\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 98,\n                    \"NameEnd\": 102\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"event_type\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 104,\n                    \"NameEnd\": 114\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"count\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 116,\n                      \"NameEnd\": 121\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 121,\n                      \"RightParenPos\": 122,\n                      \"Items\": {\n                        \"ListPos\": 122,\n                        \"ListEnd\": 122,\n                        \"HasDistinct\": false,\n                        \"Items\": []\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"count\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 127,\n                    \"NameEnd\": 132\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"uniq\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 134,\n                      \"NameEnd\": 138\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 138,\n                      \"RightParenPos\": 146,\n                      \"Items\": {\n                        \"ListPos\": 139,\n                        \"ListEnd\": 146,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": \"user_id\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 139,\n                              \"NameEnd\": 146\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"users\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 151,\n                    \"NameEnd\": 156\n                  }\n                }\n              ]\n            },\n            \"GroupBy\": {\n              \"GroupByPos\": 157,\n              \"GroupByEnd\": 182,\n              \"AggregateType\": \"\",\n              \"Expr\": {\n                \"ListPos\": 166,\n                \"ListEnd\": 182,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"hour\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 166,\n                      \"NameEnd\": 170\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"event_type\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 172,\n                      \"NameEnd\": 182\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"WithCube\": false,\n              \"WithRollup\": false,\n              \"WithTotals\": false\n            },\n            \"OrderBy\": null\n          }\n        },\n        \"After\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_attach_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 43,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"AttachPos\": 17,\n        \"Partition\": {\n          \"PartitionPos\": 24,\n          \"Expr\": {\n            \"LiteralPos\": 35,\n            \"LiteralEnd\": 43,\n            \"Literal\": \"20210114\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"From\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 46,\n    \"StatementEnd\": 101,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 58,\n        \"NameEnd\": 62\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"AttachPos\": 63,\n        \"Partition\": {\n          \"PartitionPos\": 70,\n          \"Expr\": {\n            \"LiteralPos\": 81,\n            \"LiteralEnd\": 89,\n            \"Literal\": \"20210114\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"From\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"test1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 96,\n            \"NameEnd\": 101\n          }\n        }\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 103,\n    \"StatementEnd\": 149,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 115,\n        \"NameEnd\": 119\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"AttachPos\": 120,\n        \"Partition\": {\n          \"PartitionPos\": 127,\n          \"Expr\": null,\n          \"ID\": {\n            \"LiteralPos\": 141,\n            \"LiteralEnd\": 149,\n            \"Literal\": \"20210114\"\n          },\n          \"All\": false\n        },\n        \"From\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_clear_column.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 76,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 20\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ClearPos\": 21,\n        \"StatementEnd\": 76,\n        \"IfExists\": false,\n        \"ColumnName\": {\n          \"Ident\": {\n            \"Name\": \"my_column_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 34,\n            \"NameEnd\": 48\n          },\n          \"DotIdent\": null\n        },\n        \"PartitionExpr\": {\n          \"PartitionPos\": 52,\n          \"Expr\": {\n            \"Name\": \"partition_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 62,\n            \"NameEnd\": 76\n          },\n          \"ID\": null,\n          \"All\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_clear_index.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 74,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 20\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ClearPos\": 21,\n        \"StatementEnd\": 74,\n        \"IfExists\": false,\n        \"IndexName\": {\n          \"Ident\": {\n            \"Name\": \"my_index_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 33,\n            \"NameEnd\": 46\n          },\n          \"DotIdent\": null\n        },\n        \"PartitionExpr\": {\n          \"PartitionPos\": 50,\n          \"Expr\": {\n            \"Name\": \"partition_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 60,\n            \"NameEnd\": 74\n          },\n          \"ID\": null,\n          \"All\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_clear_projection.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 71,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 20\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ClearPos\": 21,\n        \"StatementEnd\": 71,\n        \"IfExists\": false,\n        \"ProjectionName\": {\n          \"Ident\": {\n            \"Name\": \"hello\",\n            \"QuoteType\": 1,\n            \"NamePos\": 38,\n            \"NameEnd\": 43\n          },\n          \"DotIdent\": null\n        },\n        \"PartitionExpr\": {\n          \"PartitionPos\": 47,\n          \"Expr\": {\n            \"Name\": \"partition_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 57,\n            \"NameEnd\": 71\n          },\n          \"ID\": null,\n          \"All\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_delete.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 61,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 23\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"DeletePos\": 24,\n        \"StatementEnd\": 61,\n        \"WhereClause\": {\n          \"LeftExpr\": {\n            \"Name\": \"created_at\",\n            \"QuoteType\": 1,\n            \"NamePos\": 37,\n            \"NameEnd\": 47\n          },\n          \"Operation\": \"\\u003c\",\n          \"RightExpr\": {\n            \"LiteralPos\": 51,\n            \"LiteralEnd\": 61,\n            \"Literal\": \"2023-01-01\"\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_delete_with_cluster.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 96,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 23\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 24,\n      \"Expr\": {\n        \"LiteralPos\": 36,\n        \"LiteralEnd\": 51,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"DeletePos\": 53,\n        \"StatementEnd\": 96,\n        \"WhereClause\": {\n          \"LeftExpr\": {\n            \"LeftExpr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 68\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"NumPos\": 71,\n              \"NumEnd\": 74,\n              \"Literal\": \"123\",\n              \"Base\": 10\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"Operation\": \"AND\",\n          \"RightExpr\": {\n            \"LeftExpr\": {\n              \"Name\": \"status\",\n              \"QuoteType\": 1,\n              \"NamePos\": 79,\n              \"NameEnd\": 85\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"LiteralPos\": 89,\n              \"LiteralEnd\": 96,\n              \"Literal\": \"deleted\"\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_detach_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 48,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      },\n      \"Table\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 15,\n        \"NameEnd\": 19\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"DetachPos\": 27,\n        \"Partition\": {\n          \"PartitionPos\": 27,\n          \"Expr\": {\n            \"LiteralPos\": 38,\n            \"LiteralEnd\": 48,\n            \"Literal\": \"2021-10-01\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"Settings\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_drop_column.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 83,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 29\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 30,\n      \"Expr\": {\n        \"LiteralPos\": 42,\n        \"LiteralEnd\": 57,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"DropPos\": 59,\n        \"ColumnName\": {\n          \"Ident\": {\n            \"Name\": \"f1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 81,\n            \"NameEnd\": 83\n          },\n          \"DotIdent\": null\n        },\n        \"IfExists\": true\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_drop_detach_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 120,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"app_utc_00\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 22\n      },\n      \"Table\": {\n        \"Name\": \"app_message_as_notification_organization_sent_stats_i_d_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 23,\n        \"NameEnd\": 84\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"DropPos\": 85,\n        \"HasDetached\": true,\n        \"Partition\": {\n          \"PartitionPos\": 99,\n          \"Expr\": {\n            \"LiteralPos\": 110,\n            \"LiteralEnd\": 120,\n            \"Literal\": \"2022-05-24\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"Settings\": {\n          \"SettingsPos\": 122,\n          \"ListEnd\": 154,\n          \"Items\": [\n            {\n              \"SettingsPos\": 131,\n              \"Name\": {\n                \"Name\": \"allow_drop_detached\",\n                \"QuoteType\": 1,\n                \"NamePos\": 131,\n                \"NameEnd\": 150\n              },\n              \"Expr\": {\n                \"NumPos\": 153,\n                \"NumEnd\": 154,\n                \"Literal\": \"1\",\n                \"Base\": 10\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_drop_index.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 71,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"event_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 28\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 29,\n      \"Expr\": {\n        \"LiteralPos\": 41,\n        \"LiteralEnd\": 56,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"DropPos\": 58,\n        \"IndexName\": {\n          \"Ident\": {\n            \"Name\": \"f1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 69,\n            \"NameEnd\": 71\n          },\n          \"DotIdent\": null\n        },\n        \"IfExists\": false\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_drop_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 79,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 23\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 24,\n      \"Expr\": {\n        \"LiteralPos\": 36,\n        \"LiteralEnd\": 51,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"DropPos\": 53,\n        \"HasDetached\": false,\n        \"Partition\": {\n          \"PartitionPos\": 58,\n          \"Expr\": {\n            \"LiteralPos\": 69,\n            \"LiteralEnd\": 79,\n            \"Literal\": \"2023-07-18\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"Settings\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_drop_projection.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 76,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"event_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 28\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 29,\n      \"Expr\": {\n        \"LiteralPos\": 41,\n        \"LiteralEnd\": 56,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"DropPos\": 58,\n        \"ProjectionName\": {\n          \"Ident\": {\n            \"Name\": \"f1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 74,\n            \"NameEnd\": 76\n          },\n          \"DotIdent\": null\n        },\n        \"IfExists\": false\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_freeze_no_specify_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 59,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 23\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 24,\n      \"Expr\": {\n        \"LiteralPos\": 36,\n        \"LiteralEnd\": 51,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"FreezePos\": 53,\n        \"StatementEnd\": 59,\n        \"Partition\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_freeze_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 81,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 23\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 24,\n      \"Expr\": {\n        \"LiteralPos\": 36,\n        \"LiteralEnd\": 51,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"FreezePos\": 53,\n        \"StatementEnd\": 81,\n        \"Partition\": {\n          \"PartitionPos\": 60,\n          \"Expr\": {\n            \"LiteralPos\": 71,\n            \"LiteralEnd\": 81,\n            \"Literal\": \"2023-07-18\"\n          },\n          \"ID\": null,\n          \"All\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_materialize_index.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 91,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"visits_order\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 24\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"MaterializedPos\": 25,\n        \"StatementEnd\": 91,\n        \"IfExists\": true,\n        \"IndexName\": {\n          \"Ident\": {\n            \"Name\": \"user_name_index\",\n            \"QuoteType\": 1,\n            \"NamePos\": 53,\n            \"NameEnd\": 68\n          },\n          \"DotIdent\": null\n        },\n        \"Partition\": {\n          \"PartitionPos\": 72,\n          \"Expr\": {\n            \"LiteralPos\": 83,\n            \"LiteralEnd\": 91,\n            \"Literal\": \"20240403\"\n          },\n          \"ID\": null,\n          \"All\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_materialize_projection.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 101,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"visits_order\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 24\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"MaterializedPos\": 25,\n        \"StatementEnd\": 101,\n        \"IfExists\": true,\n        \"ProjectionName\": {\n          \"Ident\": {\n            \"Name\": \"user_name_projection\",\n            \"QuoteType\": 1,\n            \"NamePos\": 58,\n            \"NameEnd\": 78\n          },\n          \"DotIdent\": null\n        },\n        \"Partition\": {\n          \"PartitionPos\": 82,\n          \"Expr\": {\n            \"LiteralPos\": 93,\n            \"LiteralEnd\": 101,\n            \"Literal\": \"20240403\"\n          },\n          \"ID\": null,\n          \"All\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_modify_column.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 52,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t1\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ModifyPos\": 15,\n        \"StatementEnd\": 52,\n        \"IfExists\": false,\n        \"Column\": {\n          \"NamePos\": 29,\n          \"ColumnEnd\": 52,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 29,\n              \"NameEnd\": 31\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 32,\n              \"NameEnd\": 38\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": {\n            \"LiteralPos\": 39,\n            \"LiteralEnd\": 52,\n            \"Literal\": \"test\"\n          },\n          \"CompressionCodec\": null\n        },\n        \"RemovePropertyType\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_modify_column_remove.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 31,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t1\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ModifyPos\": 15,\n        \"StatementEnd\": 31,\n        \"IfExists\": false,\n        \"Column\": {\n          \"NamePos\": 29,\n          \"ColumnEnd\": 31,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 29,\n              \"NameEnd\": 31\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": null,\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        \"RemovePropertyType\": {\n          \"RemovePos\": 32,\n          \"PropertyType\": {\n            \"Name\": {\n              \"Name\": \"COMMENT\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 46\n            }\n          }\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_modify_setting.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 93,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"example_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 25\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ModifyPos\": 26,\n        \"StatementEnd\": 93,\n        \"Settings\": [\n          {\n            \"SettingsPos\": 41,\n            \"Name\": {\n              \"Name\": \"max_part_loading_threads\",\n              \"QuoteType\": 1,\n              \"NamePos\": 41,\n              \"NameEnd\": 65\n            },\n            \"Expr\": {\n              \"NumPos\": 66,\n              \"NumEnd\": 67,\n              \"Literal\": \"8\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 69,\n            \"Name\": {\n              \"Name\": \"max_parts_in_total\",\n              \"QuoteType\": 1,\n              \"NamePos\": 69,\n              \"NameEnd\": 87\n            },\n            \"Expr\": {\n              \"NumPos\": 88,\n              \"NumEnd\": 93,\n              \"Literal\": \"50000\",\n              \"Base\": 10\n            }\n          }\n        ]\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_remove_ttl.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 63,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 23\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 24,\n      \"Expr\": {\n        \"LiteralPos\": 36,\n        \"LiteralEnd\": 51,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"RemovePos\": 53,\n        \"StatementEnd\": 63\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_rename_column.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 69,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 20\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"RenamePos\": 21,\n        \"IfExists\": false,\n        \"OldColumnName\": {\n          \"Ident\": {\n            \"Name\": \"old_column_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 35,\n            \"NameEnd\": 50\n          },\n          \"DotIdent\": null\n        },\n        \"NewColumnName\": {\n          \"Ident\": {\n            \"Name\": \"new_column_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 54,\n            \"NameEnd\": 69\n          },\n          \"DotIdent\": null\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_replace_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 52,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t2\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ReplacePos\": 15,\n        \"Partition\": {\n          \"PartitionPos\": 23,\n          \"Expr\": {\n            \"LiteralPos\": 34,\n            \"LiteralEnd\": 43,\n            \"Literal\": \"partition\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"Table\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 50,\n            \"NameEnd\": 52\n          }\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_reset_multiple_settings.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 101,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"example_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 25\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ResetPos\": 26,\n        \"StatementEnd\": 101,\n        \"Settings\": [\n          {\n            \"Name\": \"max_part_loading_threads\",\n            \"QuoteType\": 1,\n            \"NamePos\": 40,\n            \"NameEnd\": 64\n          },\n          {\n            \"Name\": \"max_parts_in_total\",\n            \"QuoteType\": 1,\n            \"NamePos\": 66,\n            \"NameEnd\": 84\n          },\n          {\n            \"Name\": \"another_setting\",\n            \"QuoteType\": 1,\n            \"NamePos\": 86,\n            \"NameEnd\": 101\n          }\n        ]\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_reset_setting.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 64,\n    \"TableIdentifier\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"example_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 25\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"ResetPos\": 26,\n        \"StatementEnd\": 64,\n        \"Settings\": [\n          {\n            \"Name\": \"max_part_loading_threads\",\n            \"QuoteType\": 1,\n            \"NamePos\": 40,\n            \"NameEnd\": 64\n          }\n        ]\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_update.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 91,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"users\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 22\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"UpdatePos\": 23,\n        \"StatementEnd\": 91,\n        \"Assignments\": [\n          {\n            \"AssignmentPos\": 30,\n            \"Column\": {\n              \"Ident\": {\n                \"Name\": \"status\",\n                \"QuoteType\": 1,\n                \"NamePos\": 30,\n                \"NameEnd\": 36\n              },\n              \"DotIdent\": null\n            },\n            \"Expr\": {\n              \"LiteralPos\": 40,\n              \"LiteralEnd\": 46,\n              \"Literal\": \"active\"\n            }\n          },\n          {\n            \"AssignmentPos\": 49,\n            \"Column\": {\n              \"Ident\": {\n                \"Name\": \"updated_at\",\n                \"QuoteType\": 1,\n                \"NamePos\": 49,\n                \"NameEnd\": 59\n              },\n              \"DotIdent\": null\n            },\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"now\",\n                \"QuoteType\": 1,\n                \"NamePos\": 62,\n                \"NameEnd\": 65\n              },\n              \"Params\": {\n                \"LeftParenPos\": 65,\n                \"RightParenPos\": 66,\n                \"Items\": {\n                  \"ListPos\": 66,\n                  \"ListEnd\": 66,\n                  \"HasDistinct\": false,\n                  \"Items\": []\n                },\n                \"ColumnArgList\": null\n              }\n            }\n          }\n        ],\n        \"InPartition\": null,\n        \"WhereClause\": {\n          \"LeftExpr\": {\n            \"Name\": \"status\",\n            \"QuoteType\": 1,\n            \"NamePos\": 74,\n            \"NameEnd\": 80\n          },\n          \"Operation\": \"=\",\n          \"RightExpr\": {\n            \"LiteralPos\": 84,\n            \"LiteralEnd\": 91,\n            \"Literal\": \"pending\"\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_update_in_partition.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 98,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"users\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 22\n      }\n    },\n    \"OnCluster\": null,\n    \"AlterExprs\": [\n      {\n        \"UpdatePos\": 23,\n        \"StatementEnd\": 98,\n        \"Assignments\": [\n          {\n            \"AssignmentPos\": 30,\n            \"Column\": {\n              \"Ident\": {\n                \"Name\": \"status\",\n                \"QuoteType\": 1,\n                \"NamePos\": 30,\n                \"NameEnd\": 36\n              },\n              \"DotIdent\": null\n            },\n            \"Expr\": {\n              \"LiteralPos\": 40,\n              \"LiteralEnd\": 48,\n              \"Literal\": \"inactive\"\n            }\n          }\n        ],\n        \"InPartition\": {\n          \"PartitionPos\": 53,\n          \"Expr\": {\n            \"LiteralPos\": 64,\n            \"LiteralEnd\": 74,\n            \"Literal\": \"2024-01-01\"\n          },\n          \"ID\": null,\n          \"All\": false\n        },\n        \"WhereClause\": {\n          \"LeftExpr\": {\n            \"Name\": \"status\",\n            \"QuoteType\": 1,\n            \"NamePos\": 82,\n            \"NameEnd\": 88\n          },\n          \"Operation\": \"=\",\n          \"RightExpr\": {\n            \"LiteralPos\": 92,\n            \"LiteralEnd\": 98,\n            \"Literal\": \"active\"\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/alter_table_update_with_cluster.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 84,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 15,\n        \"NameEnd\": 20\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 21,\n      \"Expr\": {\n        \"Name\": \"cluster1\",\n        \"QuoteType\": 1,\n        \"NamePos\": 32,\n        \"NameEnd\": 40\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"UpdatePos\": 41,\n        \"StatementEnd\": 84,\n        \"Assignments\": [\n          {\n            \"AssignmentPos\": 48,\n            \"Column\": {\n              \"Ident\": {\n                \"Name\": \"column1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 48,\n                \"NameEnd\": 55\n              },\n              \"DotIdent\": null\n            },\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"column1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 58,\n                \"NameEnd\": 65\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"NumPos\": 68,\n                \"NumEnd\": 69,\n                \"Literal\": \"1\",\n                \"Base\": 10\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            }\n          }\n        ],\n        \"InPartition\": null,\n        \"WhereClause\": {\n          \"LeftExpr\": {\n            \"Name\": \"id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 76,\n            \"NameEnd\": 78\n          },\n          \"Operation\": \"\\u003e\",\n          \"RightExpr\": {\n            \"NumPos\": 81,\n            \"NumEnd\": 84,\n            \"Literal\": \"100\",\n            \"Base\": 10\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/attach_table_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 399,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 31\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 32,\n        \"NameEnd\": 44\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 45,\n      \"Expr\": {\n        \"LiteralPos\": 57,\n        \"LiteralEnd\": 72,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 74,\n      \"SchemaEnd\": 227,\n      \"Columns\": [\n        {\n          \"NamePos\": 80,\n          \"ColumnEnd\": 89,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 80,\n              \"NameEnd\": 82\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 83,\n              \"NameEnd\": 89\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 95,\n          \"ColumnEnd\": 104,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 95,\n              \"NameEnd\": 97\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 98,\n              \"NameEnd\": 104\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 110,\n          \"ColumnEnd\": 119,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 110,\n              \"NameEnd\": 112\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 113,\n              \"NameEnd\": 119\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 125,\n          \"ColumnEnd\": 136,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 125,\n              \"NameEnd\": 127\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 128,\n              \"NameEnd\": 136\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 142,\n          \"ColumnEnd\": 153,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 142,\n              \"NameEnd\": 144\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 145,\n              \"NameEnd\": 153\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 159,\n          \"ColumnEnd\": 179,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 159,\n              \"NameEnd\": 161\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 166,\n            \"RightParenPos\": 179,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 162,\n              \"NameEnd\": 165\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 166,\n                  \"NameEnd\": 172\n                }\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 173,\n                  \"NameEnd\": 179\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 186,\n          \"ColumnEnd\": 195,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 1,\n              \"NamePos\": 186,\n              \"NameEnd\": 188\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 189,\n              \"NameEnd\": 195\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 201,\n          \"ColumnEnd\": 225,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f7\",\n              \"QuoteType\": 1,\n              \"NamePos\": 201,\n              \"NameEnd\": 203\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 204,\n              \"NameEnd\": 212\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"Name\": {\n              \"Name\": \"now\",\n              \"QuoteType\": 1,\n              \"NamePos\": 221,\n              \"NameEnd\": 224\n            },\n            \"Params\": {\n              \"LeftParenPos\": 224,\n              \"RightParenPos\": 225,\n              \"Items\": {\n                \"ListPos\": 225,\n                \"ListEnd\": 225,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 229,\n      \"EngineEnd\": 399,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 257,\n        \"RightParenPos\": 325,\n        \"Items\": {\n          \"ListPos\": 259,\n          \"ListEnd\": 324,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 259,\n                \"LiteralEnd\": 311,\n                \"Literal\": \"/clickhouse/tables/{layer}-{shard}/test/events_local\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 315,\n                \"LiteralEnd\": 324,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 353,\n        \"Expr\": {\n          \"ListPos\": 366,\n          \"ListEnd\": 379,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMMDD\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 366,\n                  \"NameEnd\": 376\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 376,\n                  \"RightParenPos\": 379,\n                  \"Items\": {\n                    \"ListPos\": 377,\n                    \"ListEnd\": 379,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f3\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 377,\n                          \"NameEnd\": 379\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 327,\n        \"ListEnd\": 352,\n        \"Items\": [\n          {\n            \"TTLPos\": 327,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"f3\",\n                \"QuoteType\": 1,\n                \"NamePos\": 331,\n                \"NameEnd\": 333\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 336,\n                \"Expr\": {\n                  \"NumPos\": 345,\n                  \"NumEnd\": 346,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 347,\n                  \"NameEnd\": 352\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 381,\n        \"ListEnd\": 399,\n        \"Items\": [\n          {\n            \"OrderPos\": 381,\n            \"Expr\": {\n              \"LeftParenPos\": 390,\n              \"RightParenPos\": 399,\n              \"Items\": {\n                \"ListPos\": 391,\n                \"ListEnd\": 399,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 391,\n                      \"NameEnd\": 393\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 394,\n                      \"NameEnd\": 396\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 397,\n                      \"NameEnd\": 399\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/bug_001.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 635,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 39,\n        \"NameEnd\": 41\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 42,\n        \"NameEnd\": 47\n      }\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": {\n      \"OnPos\": 60,\n      \"Expr\": {\n        \"LiteralPos\": 72,\n        \"LiteralEnd\": 87,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": null,\n    \"HasEmpty\": false,\n    \"Destination\": {\n      \"ToPos\": 89,\n      \"TableIdentifier\": {\n        \"Database\": {\n          \"Name\": \"db\",\n          \"QuoteType\": 1,\n          \"NamePos\": 92,\n          \"NameEnd\": 94\n        },\n        \"Table\": {\n          \"Name\": \"table_mv\",\n          \"QuoteType\": 1,\n          \"NamePos\": 95,\n          \"NameEnd\": 103\n        }\n      },\n      \"TableSchema\": null\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 107,\n        \"StatementEnd\": 635,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"event_ts\",\n              \"QuoteType\": 1,\n              \"NamePos\": 118,\n              \"NameEnd\": 126\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"org_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 132,\n              \"NameEnd\": 138\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 144,\n                \"NameEnd\": 167\n              },\n              \"Params\": {\n                \"LeftParenPos\": 167,\n                \"RightParenPos\": 183,\n                \"Items\": {\n                  \"ListPos\": 168,\n                  \"ListEnd\": 182,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 168,\n                        \"NameEnd\": 178\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 181,\n                        \"LiteralEnd\": 182,\n                        \"Literal\": \"x\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"x\",\n              \"QuoteType\": 1,\n              \"NamePos\": 188,\n              \"NameEnd\": 189\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 195,\n                \"NameEnd\": 218\n              },\n              \"Params\": {\n                \"LeftParenPos\": 218,\n                \"RightParenPos\": 234,\n                \"Items\": {\n                  \"ListPos\": 219,\n                  \"ListEnd\": 233,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 219,\n                        \"NameEnd\": 229\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 232,\n                        \"LiteralEnd\": 233,\n                        \"Literal\": \"y\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"y\",\n              \"QuoteType\": 1,\n              \"NamePos\": 239,\n              \"NameEnd\": 240\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 246,\n                \"NameEnd\": 269\n              },\n              \"Params\": {\n                \"LeftParenPos\": 269,\n                \"RightParenPos\": 285,\n                \"Items\": {\n                  \"ListPos\": 270,\n                  \"ListEnd\": 284,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 270,\n                        \"NameEnd\": 280\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 283,\n                        \"LiteralEnd\": 284,\n                        \"Literal\": \"z\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"z\",\n              \"QuoteType\": 1,\n              \"NamePos\": 290,\n              \"NameEnd\": 291\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 297,\n                \"NameEnd\": 320\n              },\n              \"Params\": {\n                \"LeftParenPos\": 320,\n                \"RightParenPos\": 336,\n                \"Items\": {\n                  \"ListPos\": 321,\n                  \"ListEnd\": 335,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 321,\n                        \"NameEnd\": 331\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 334,\n                        \"LiteralEnd\": 335,\n                        \"Literal\": \"a\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"a\",\n              \"QuoteType\": 1,\n              \"NamePos\": 341,\n              \"NameEnd\": 342\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 348,\n                \"NameEnd\": 371\n              },\n              \"Params\": {\n                \"LeftParenPos\": 371,\n                \"RightParenPos\": 387,\n                \"Items\": {\n                  \"ListPos\": 372,\n                  \"ListEnd\": 386,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 372,\n                        \"NameEnd\": 382\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 385,\n                        \"LiteralEnd\": 386,\n                        \"Literal\": \"b\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"b\",\n              \"QuoteType\": 1,\n              \"NamePos\": 392,\n              \"NameEnd\": 393\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 399,\n                \"NameEnd\": 422\n              },\n              \"Params\": {\n                \"LeftParenPos\": 422,\n                \"RightParenPos\": 438,\n                \"Items\": {\n                  \"ListPos\": 423,\n                  \"ListEnd\": 437,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 423,\n                        \"NameEnd\": 433\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 436,\n                        \"LiteralEnd\": 437,\n                        \"Literal\": \"c\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"c\",\n              \"QuoteType\": 1,\n              \"NamePos\": 443,\n              \"NameEnd\": 444\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 450,\n                \"NameEnd\": 473\n              },\n              \"Params\": {\n                \"LeftParenPos\": 473,\n                \"RightParenPos\": 489,\n                \"Items\": {\n                  \"ListPos\": 474,\n                  \"ListEnd\": 488,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 474,\n                        \"NameEnd\": 484\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 487,\n                        \"LiteralEnd\": 488,\n                        \"Literal\": \"d\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 494,\n              \"NameEnd\": 495\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractInt\",\n                \"QuoteType\": 1,\n                \"NamePos\": 501,\n                \"NameEnd\": 521\n              },\n              \"Params\": {\n                \"LeftParenPos\": 521,\n                \"RightParenPos\": 537,\n                \"Items\": {\n                  \"ListPos\": 522,\n                  \"ListEnd\": 536,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 522,\n                        \"NameEnd\": 532\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 535,\n                        \"LiteralEnd\": 536,\n                        \"Literal\": \"e\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"e\",\n              \"QuoteType\": 1,\n              \"NamePos\": 542,\n              \"NameEnd\": 543\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractInt\",\n                \"QuoteType\": 1,\n                \"NamePos\": 549,\n                \"NameEnd\": 569\n              },\n              \"Params\": {\n                \"LeftParenPos\": 569,\n                \"RightParenPos\": 585,\n                \"Items\": {\n                  \"ListPos\": 570,\n                  \"ListEnd\": 584,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 570,\n                        \"NameEnd\": 580\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 583,\n                        \"LiteralEnd\": 584,\n                        \"Literal\": \"f\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f\",\n              \"QuoteType\": 1,\n              \"NamePos\": 590,\n              \"NameEnd\": 591\n            }\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 592,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 597,\n              \"TableEnd\": 605,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": {\n                  \"Name\": \"db\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 597,\n                  \"NameEnd\": 599\n                },\n                \"Table\": {\n                  \"Name\": \"table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 600,\n                  \"NameEnd\": 605\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 605,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": {\n          \"WherePos\": 606,\n          \"Expr\": {\n            \"LeftExpr\": {\n              \"Fields\": [\n                {\n                  \"Name\": \"db\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 612,\n                  \"NameEnd\": 614\n                },\n                {\n                  \"Name\": \"table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 615,\n                  \"NameEnd\": 620\n                },\n                {\n                  \"Name\": \"event\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 621,\n                  \"NameEnd\": 626\n                }\n              ]\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"LiteralPos\": 630,\n              \"LiteralEnd\": 635,\n              \"Literal\": \"hello\"\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          }\n        },\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/check.sql.golden.json",
    "content": "[\n  {\n    \"CheckPos\": 0,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 22\n      }\n    },\n    \"Partition\": null\n  },\n  {\n    \"CheckPos\": 24,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 36,\n        \"NameEnd\": 46\n      }\n    },\n    \"Partition\": {\n      \"PartitionPos\": 47,\n      \"Expr\": {\n        \"LiteralPos\": 58,\n        \"LiteralEnd\": 61,\n        \"Literal\": \"col\"\n      },\n      \"ID\": null,\n      \"All\": false\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_database.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 35,\n    \"Name\": {\n      \"Name\": \"test\",\n      \"QuoteType\": 3,\n      \"NamePos\": 31,\n      \"NameEnd\": 35\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": null,\n    \"Engine\": null,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_database_replicated.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 54,\n    \"Name\": {\n      \"Name\": \"test\",\n      \"QuoteType\": 3,\n      \"NamePos\": 31,\n      \"NameEnd\": 35\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": null,\n    \"Engine\": {\n      \"EnginePos\": 37,\n      \"EngineEnd\": 54,\n      \"Name\": \"Replicated\",\n      \"Params\": {\n        \"LeftParenPos\": 54,\n        \"RightParenPos\": 93,\n        \"Items\": {\n          \"ListPos\": 56,\n          \"ListEnd\": 92,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 56,\n                \"LiteralEnd\": 72,\n                \"Literal\": \"/root/test_local\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 76,\n                \"LiteralEnd\": 81,\n                \"Literal\": \"shard\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 85,\n                \"LiteralEnd\": 92,\n                \"Literal\": \"replica\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": null\n    },\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_dictionary_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 444,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 22\n      },\n      \"Table\": {\n        \"Name\": \"my_dict\",\n        \"QuoteType\": 1,\n        \"NamePos\": 23,\n        \"NameEnd\": 30\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"Schema\": {\n      \"SchemaPos\": 31,\n      \"Attributes\": [\n        {\n          \"NamePos\": 37,\n          \"Name\": {\n            \"Name\": \"id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 37,\n            \"NameEnd\": 39\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 40,\n              \"NameEnd\": 46\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 52,\n          \"Name\": {\n            \"Name\": \"name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 52,\n            \"NameEnd\": 56\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 57,\n              \"NameEnd\": 63\n            }\n          },\n          \"Default\": {\n            \"LiteralPos\": 73,\n            \"LiteralEnd\": 73,\n            \"Literal\": \"\"\n          },\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 80,\n          \"Name\": {\n            \"Name\": \"value\",\n            \"QuoteType\": 1,\n            \"NamePos\": 80,\n            \"NameEnd\": 85\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Float64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 86,\n              \"NameEnd\": 93\n            }\n          },\n          \"Default\": null,\n          \"Expression\": {\n            \"Name\": {\n              \"Name\": \"toFloat64OrZero\",\n              \"QuoteType\": 1,\n              \"NamePos\": 105,\n              \"NameEnd\": 120\n            },\n            \"Params\": {\n              \"LeftParenPos\": 120,\n              \"RightParenPos\": 125,\n              \"Items\": {\n                \"ListPos\": 121,\n                \"ListEnd\": 125,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 121,\n                      \"NameEnd\": 125\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 132,\n          \"Name\": {\n            \"Name\": \"parent_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 132,\n            \"NameEnd\": 141\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 142,\n              \"NameEnd\": 148\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": true,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 167,\n          \"Name\": {\n            \"Name\": \"is_active\",\n            \"QuoteType\": 1,\n            \"NamePos\": 167,\n            \"NameEnd\": 176\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 177,\n              \"NameEnd\": 182\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": true,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 198,\n          \"Name\": {\n            \"Name\": \"object_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 198,\n            \"NameEnd\": 207\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 208,\n              \"NameEnd\": 214\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": true\n        }\n      ],\n      \"RParenPos\": 228\n    },\n    \"Engine\": {\n      \"EnginePos\": 230,\n      \"PrimaryKey\": {\n        \"PrimaryKeyPos\": 230,\n        \"Keys\": {\n          \"ListPos\": 242,\n          \"ListEnd\": 244,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"id\",\n                \"QuoteType\": 1,\n                \"NamePos\": 242,\n                \"NameEnd\": 244\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"RParenPos\": 243\n      },\n      \"Source\": {\n        \"SourcePos\": 245,\n        \"Source\": {\n          \"Name\": \"MYSQL\",\n          \"QuoteType\": 1,\n          \"NamePos\": 252,\n          \"NameEnd\": 257\n        },\n        \"Args\": [\n          {\n            \"ArgPos\": 263,\n            \"Name\": {\n              \"Name\": \"host\",\n              \"QuoteType\": 1,\n              \"NamePos\": 263,\n              \"NameEnd\": 267\n            },\n            \"Value\": {\n              \"LiteralPos\": 269,\n              \"LiteralEnd\": 278,\n              \"Literal\": \"localhost\"\n            }\n          },\n          {\n            \"ArgPos\": 284,\n            \"Name\": {\n              \"Name\": \"port\",\n              \"QuoteType\": 1,\n              \"NamePos\": 284,\n              \"NameEnd\": 288\n            },\n            \"Value\": {\n              \"NumPos\": 289,\n              \"NumEnd\": 293,\n              \"Literal\": \"3306\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"ArgPos\": 298,\n            \"Name\": {\n              \"Name\": \"user\",\n              \"QuoteType\": 1,\n              \"NamePos\": 298,\n              \"NameEnd\": 302\n            },\n            \"Value\": {\n              \"LiteralPos\": 304,\n              \"LiteralEnd\": 311,\n              \"Literal\": \"default\"\n            }\n          },\n          {\n            \"ArgPos\": 317,\n            \"Name\": {\n              \"Name\": \"password\",\n              \"QuoteType\": 1,\n              \"NamePos\": 317,\n              \"NameEnd\": 325\n            },\n            \"Value\": {\n              \"LiteralPos\": 327,\n              \"LiteralEnd\": 327,\n              \"Literal\": \"\"\n            }\n          },\n          {\n            \"ArgPos\": 333,\n            \"Name\": {\n              \"Name\": \"db\",\n              \"QuoteType\": 1,\n              \"NamePos\": 333,\n              \"NameEnd\": 335\n            },\n            \"Value\": {\n              \"LiteralPos\": 337,\n              \"LiteralEnd\": 341,\n              \"Literal\": \"test\"\n            }\n          },\n          {\n            \"ArgPos\": 347,\n            \"Name\": {\n              \"Name\": \"table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 347,\n              \"NameEnd\": 352\n            },\n            \"Value\": {\n              \"LiteralPos\": 354,\n              \"LiteralEnd\": 364,\n              \"Literal\": \"dict_table\"\n            }\n          }\n        ],\n        \"RParenPos\": 367\n      },\n      \"Lifetime\": {\n        \"LifetimePos\": 369,\n        \"Min\": {\n          \"NumPos\": 382,\n          \"NumEnd\": 386,\n          \"Literal\": \"1000\",\n          \"Base\": 10\n        },\n        \"Max\": {\n          \"NumPos\": 391,\n          \"NumEnd\": 395,\n          \"Literal\": \"2000\",\n          \"Base\": 10\n        },\n        \"Value\": null,\n        \"RParenPos\": 395\n      },\n      \"Layout\": {\n        \"LayoutPos\": 397,\n        \"Layout\": {\n          \"Name\": \"HASHED\",\n          \"QuoteType\": 1,\n          \"NamePos\": 404,\n          \"NameEnd\": 410\n        },\n        \"Args\": null,\n        \"RParenPos\": 412\n      },\n      \"Range\": null,\n      \"Settings\": {\n        \"SettingsPos\": 414,\n        \"ListEnd\": 444,\n        \"Items\": [\n          {\n            \"SettingsPos\": 423,\n            \"Name\": {\n              \"Name\": \"max_block_size\",\n              \"QuoteType\": 1,\n              \"NamePos\": 423,\n              \"NameEnd\": 437\n            },\n            \"Expr\": {\n              \"NumPos\": 440,\n              \"NumEnd\": 444,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      }\n    },\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_dictionary_comprehensive.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 586,\n    \"OrReplace\": true,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 29,\n        \"NameEnd\": 33\n      },\n      \"Table\": {\n        \"Name\": \"comprehensive_dict\",\n        \"QuoteType\": 1,\n        \"NamePos\": 34,\n        \"NameEnd\": 52\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": {\n      \"Value\": {\n        \"LiteralPos\": 60,\n        \"LiteralEnd\": 96,\n        \"Literal\": \"12345678-1234-1234-1234-123456789012\"\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 98,\n      \"Expr\": {\n        \"Name\": \"production_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 109,\n        \"NameEnd\": 127\n      }\n    },\n    \"Schema\": {\n      \"SchemaPos\": 128,\n      \"Attributes\": [\n        {\n          \"NamePos\": 134,\n          \"Name\": {\n            \"Name\": \"id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 134,\n            \"NameEnd\": 136\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 137,\n              \"NameEnd\": 143\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 149,\n          \"Name\": {\n            \"Name\": \"name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 149,\n            \"NameEnd\": 153\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 154,\n              \"NameEnd\": 160\n            }\n          },\n          \"Default\": {\n            \"LiteralPos\": 170,\n            \"LiteralEnd\": 170,\n            \"Literal\": \"\"\n          },\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 177,\n          \"Name\": {\n            \"Name\": \"value\",\n            \"QuoteType\": 1,\n            \"NamePos\": 177,\n            \"NameEnd\": 182\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Float64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 183,\n              \"NameEnd\": 190\n            }\n          },\n          \"Default\": null,\n          \"Expression\": {\n            \"Name\": {\n              \"Name\": \"toFloat64OrZero\",\n              \"QuoteType\": 1,\n              \"NamePos\": 202,\n              \"NameEnd\": 217\n            },\n            \"Params\": {\n              \"LeftParenPos\": 217,\n              \"RightParenPos\": 222,\n              \"Items\": {\n                \"ListPos\": 218,\n                \"ListEnd\": 222,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 218,\n                      \"NameEnd\": 222\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 229,\n          \"Name\": {\n            \"Name\": \"parent_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 229,\n            \"NameEnd\": 238\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 239,\n              \"NameEnd\": 245\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": true,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 264,\n          \"Name\": {\n            \"Name\": \"is_active\",\n            \"QuoteType\": 1,\n            \"NamePos\": 264,\n            \"NameEnd\": 273\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 274,\n              \"NameEnd\": 279\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": true,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 295,\n          \"Name\": {\n            \"Name\": \"object_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 295,\n            \"NameEnd\": 304\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 305,\n              \"NameEnd\": 311\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": true\n        }\n      ],\n      \"RParenPos\": 325\n    },\n    \"Engine\": {\n      \"EnginePos\": 327,\n      \"PrimaryKey\": {\n        \"PrimaryKeyPos\": 327,\n        \"Keys\": {\n          \"ListPos\": 339,\n          \"ListEnd\": 341,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"id\",\n                \"QuoteType\": 1,\n                \"NamePos\": 339,\n                \"NameEnd\": 341\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"RParenPos\": 340\n      },\n      \"Source\": {\n        \"SourcePos\": 342,\n        \"Source\": {\n          \"Name\": \"MYSQL\",\n          \"QuoteType\": 1,\n          \"NamePos\": 349,\n          \"NameEnd\": 354\n        },\n        \"Args\": [\n          {\n            \"ArgPos\": 360,\n            \"Name\": {\n              \"Name\": \"host\",\n              \"QuoteType\": 1,\n              \"NamePos\": 360,\n              \"NameEnd\": 364\n            },\n            \"Value\": {\n              \"LiteralPos\": 366,\n              \"LiteralEnd\": 375,\n              \"Literal\": \"localhost\"\n            }\n          },\n          {\n            \"ArgPos\": 381,\n            \"Name\": {\n              \"Name\": \"port\",\n              \"QuoteType\": 1,\n              \"NamePos\": 381,\n              \"NameEnd\": 385\n            },\n            \"Value\": {\n              \"NumPos\": 386,\n              \"NumEnd\": 390,\n              \"Literal\": \"3306\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"ArgPos\": 395,\n            \"Name\": {\n              \"Name\": \"user\",\n              \"QuoteType\": 1,\n              \"NamePos\": 395,\n              \"NameEnd\": 399\n            },\n            \"Value\": {\n              \"LiteralPos\": 401,\n              \"LiteralEnd\": 405,\n              \"Literal\": \"root\"\n            }\n          },\n          {\n            \"ArgPos\": 411,\n            \"Name\": {\n              \"Name\": \"password\",\n              \"QuoteType\": 1,\n              \"NamePos\": 411,\n              \"NameEnd\": 419\n            },\n            \"Value\": {\n              \"LiteralPos\": 421,\n              \"LiteralEnd\": 427,\n              \"Literal\": \"secret\"\n            }\n          },\n          {\n            \"ArgPos\": 433,\n            \"Name\": {\n              \"Name\": \"db\",\n              \"QuoteType\": 1,\n              \"NamePos\": 433,\n              \"NameEnd\": 435\n            },\n            \"Value\": {\n              \"LiteralPos\": 437,\n              \"LiteralEnd\": 444,\n              \"Literal\": \"test_db\"\n            }\n          },\n          {\n            \"ArgPos\": 450,\n            \"Name\": {\n              \"Name\": \"table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 450,\n              \"NameEnd\": 455\n            },\n            \"Value\": {\n              \"LiteralPos\": 457,\n              \"LiteralEnd\": 473,\n              \"Literal\": \"dictionary_table\"\n            }\n          }\n        ],\n        \"RParenPos\": 476\n      },\n      \"Lifetime\": {\n        \"LifetimePos\": 478,\n        \"Min\": {\n          \"NumPos\": 491,\n          \"NumEnd\": 495,\n          \"Literal\": \"1000\",\n          \"Base\": 10\n        },\n        \"Max\": {\n          \"NumPos\": 500,\n          \"NumEnd\": 504,\n          \"Literal\": \"2000\",\n          \"Base\": 10\n        },\n        \"Value\": null,\n        \"RParenPos\": 504\n      },\n      \"Layout\": {\n        \"LayoutPos\": 506,\n        \"Layout\": {\n          \"Name\": \"HASHED\",\n          \"QuoteType\": 1,\n          \"NamePos\": 513,\n          \"NameEnd\": 519\n        },\n        \"Args\": null,\n        \"RParenPos\": 521\n      },\n      \"Range\": null,\n      \"Settings\": {\n        \"SettingsPos\": 523,\n        \"ListEnd\": 586,\n        \"Items\": [\n          {\n            \"SettingsPos\": 532,\n            \"Name\": {\n              \"Name\": \"max_block_size\",\n              \"QuoteType\": 1,\n              \"NamePos\": 532,\n              \"NameEnd\": 546\n            },\n            \"Expr\": {\n              \"NumPos\": 549,\n              \"NumEnd\": 553,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 555,\n            \"Name\": {\n              \"Name\": \"max_insert_block_size\",\n              \"QuoteType\": 1,\n              \"NamePos\": 555,\n              \"NameEnd\": 576\n            },\n            \"Expr\": {\n              \"NumPos\": 579,\n              \"NumEnd\": 586,\n              \"Literal\": \"1048576\",\n              \"Base\": 10\n            }\n          }\n        ]\n      }\n    },\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_dictionary_with_comment.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 493,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 22\n      },\n      \"Table\": {\n        \"Name\": \"my_dict\",\n        \"QuoteType\": 1,\n        \"NamePos\": 23,\n        \"NameEnd\": 30\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"Schema\": {\n      \"SchemaPos\": 31,\n      \"Attributes\": [\n        {\n          \"NamePos\": 37,\n          \"Name\": {\n            \"Name\": \"id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 37,\n            \"NameEnd\": 39\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 40,\n              \"NameEnd\": 46\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 52,\n          \"Name\": {\n            \"Name\": \"name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 52,\n            \"NameEnd\": 56\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 57,\n              \"NameEnd\": 63\n            }\n          },\n          \"Default\": {\n            \"LiteralPos\": 73,\n            \"LiteralEnd\": 73,\n            \"Literal\": \"\"\n          },\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 80,\n          \"Name\": {\n            \"Name\": \"value\",\n            \"QuoteType\": 1,\n            \"NamePos\": 80,\n            \"NameEnd\": 85\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Float64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 86,\n              \"NameEnd\": 93\n            }\n          },\n          \"Default\": null,\n          \"Expression\": {\n            \"Name\": {\n              \"Name\": \"toFloat64OrZero\",\n              \"QuoteType\": 1,\n              \"NamePos\": 105,\n              \"NameEnd\": 120\n            },\n            \"Params\": {\n              \"LeftParenPos\": 120,\n              \"RightParenPos\": 125,\n              \"Items\": {\n                \"ListPos\": 121,\n                \"ListEnd\": 125,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 121,\n                      \"NameEnd\": 125\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 132,\n          \"Name\": {\n            \"Name\": \"parent_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 132,\n            \"NameEnd\": 141\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 142,\n              \"NameEnd\": 148\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": true,\n          \"Injective\": false,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 167,\n          \"Name\": {\n            \"Name\": \"is_active\",\n            \"QuoteType\": 1,\n            \"NamePos\": 167,\n            \"NameEnd\": 176\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 177,\n              \"NameEnd\": 182\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": true,\n          \"IsObjectId\": false\n        },\n        {\n          \"NamePos\": 198,\n          \"Name\": {\n            \"Name\": \"object_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 198,\n            \"NameEnd\": 207\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 208,\n              \"NameEnd\": 214\n            }\n          },\n          \"Default\": null,\n          \"Expression\": null,\n          \"Hierarchical\": false,\n          \"Injective\": false,\n          \"IsObjectId\": true\n        }\n      ],\n      \"RParenPos\": 228\n    },\n    \"Engine\": {\n      \"EnginePos\": 230,\n      \"PrimaryKey\": {\n        \"PrimaryKeyPos\": 230,\n        \"Keys\": {\n          \"ListPos\": 242,\n          \"ListEnd\": 244,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"id\",\n                \"QuoteType\": 1,\n                \"NamePos\": 242,\n                \"NameEnd\": 244\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"RParenPos\": 243\n      },\n      \"Source\": {\n        \"SourcePos\": 245,\n        \"Source\": {\n          \"Name\": \"MYSQL\",\n          \"QuoteType\": 1,\n          \"NamePos\": 252,\n          \"NameEnd\": 257\n        },\n        \"Args\": [\n          {\n            \"ArgPos\": 263,\n            \"Name\": {\n              \"Name\": \"host\",\n              \"QuoteType\": 1,\n              \"NamePos\": 263,\n              \"NameEnd\": 267\n            },\n            \"Value\": {\n              \"LiteralPos\": 269,\n              \"LiteralEnd\": 278,\n              \"Literal\": \"localhost\"\n            }\n          },\n          {\n            \"ArgPos\": 284,\n            \"Name\": {\n              \"Name\": \"port\",\n              \"QuoteType\": 1,\n              \"NamePos\": 284,\n              \"NameEnd\": 288\n            },\n            \"Value\": {\n              \"NumPos\": 289,\n              \"NumEnd\": 293,\n              \"Literal\": \"3306\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"ArgPos\": 298,\n            \"Name\": {\n              \"Name\": \"user\",\n              \"QuoteType\": 1,\n              \"NamePos\": 298,\n              \"NameEnd\": 302\n            },\n            \"Value\": {\n              \"LiteralPos\": 304,\n              \"LiteralEnd\": 311,\n              \"Literal\": \"default\"\n            }\n          },\n          {\n            \"ArgPos\": 317,\n            \"Name\": {\n              \"Name\": \"password\",\n              \"QuoteType\": 1,\n              \"NamePos\": 317,\n              \"NameEnd\": 325\n            },\n            \"Value\": {\n              \"LiteralPos\": 327,\n              \"LiteralEnd\": 327,\n              \"Literal\": \"\"\n            }\n          },\n          {\n            \"ArgPos\": 333,\n            \"Name\": {\n              \"Name\": \"db\",\n              \"QuoteType\": 1,\n              \"NamePos\": 333,\n              \"NameEnd\": 335\n            },\n            \"Value\": {\n              \"LiteralPos\": 337,\n              \"LiteralEnd\": 341,\n              \"Literal\": \"test\"\n            }\n          },\n          {\n            \"ArgPos\": 347,\n            \"Name\": {\n              \"Name\": \"table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 347,\n              \"NameEnd\": 352\n            },\n            \"Value\": {\n              \"LiteralPos\": 354,\n              \"LiteralEnd\": 364,\n              \"Literal\": \"dict_table\"\n            }\n          }\n        ],\n        \"RParenPos\": 367\n      },\n      \"Lifetime\": {\n        \"LifetimePos\": 369,\n        \"Min\": {\n          \"NumPos\": 382,\n          \"NumEnd\": 386,\n          \"Literal\": \"1000\",\n          \"Base\": 10\n        },\n        \"Max\": {\n          \"NumPos\": 391,\n          \"NumEnd\": 395,\n          \"Literal\": \"2000\",\n          \"Base\": 10\n        },\n        \"Value\": null,\n        \"RParenPos\": 395\n      },\n      \"Layout\": {\n        \"LayoutPos\": 397,\n        \"Layout\": {\n          \"Name\": \"HASHED\",\n          \"QuoteType\": 1,\n          \"NamePos\": 404,\n          \"NameEnd\": 410\n        },\n        \"Args\": null,\n        \"RParenPos\": 412\n      },\n      \"Range\": null,\n      \"Settings\": {\n        \"SettingsPos\": 414,\n        \"ListEnd\": 444,\n        \"Items\": [\n          {\n            \"SettingsPos\": 423,\n            \"Name\": {\n              \"Name\": \"max_block_size\",\n              \"QuoteType\": 1,\n              \"NamePos\": 423,\n              \"NameEnd\": 437\n            },\n            \"Expr\": {\n              \"NumPos\": 440,\n              \"NumEnd\": 444,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      }\n    },\n    \"Comment\": {\n      \"LiteralPos\": 455,\n      \"LiteralEnd\": 493,\n      \"Literal\": \"This is a test dictionary with comment\"\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_distributed_table.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 191,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \"event_all\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 27\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 28,\n      \"Expr\": {\n        \"LiteralPos\": 40,\n        \"LiteralEnd\": 55,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 57,\n      \"SchemaEnd\": 77,\n      \"Columns\": null,\n      \"AliasTable\": {\n        \"Database\": {\n          \"Name\": \"test\",\n          \"QuoteType\": 1,\n          \"NamePos\": 60,\n          \"NameEnd\": 64\n        },\n        \"Table\": {\n          \"Name\": \"evnets_local\",\n          \"QuoteType\": 1,\n          \"NamePos\": 65,\n          \"NameEnd\": 77\n        }\n      },\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 78,\n      \"EngineEnd\": 191,\n      \"Name\": \"Distributed\",\n      \"Params\": {\n        \"LeftParenPos\": 98,\n        \"RightParenPos\": 160,\n        \"Items\": {\n          \"ListPos\": 104,\n          \"ListEnd\": 158,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"default_cluster\",\n                \"QuoteType\": 1,\n                \"NamePos\": 104,\n                \"NameEnd\": 119\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"Name\": \"test\",\n                \"QuoteType\": 1,\n                \"NamePos\": 125,\n                \"NameEnd\": 129\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"Name\": \"events_local\",\n                \"QuoteType\": 1,\n                \"NamePos\": 135,\n                \"NameEnd\": 147\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"rand\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 153,\n                  \"NameEnd\": 157\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 157,\n                  \"RightParenPos\": 158,\n                  \"Items\": {\n                    \"ListPos\": 158,\n                    \"ListEnd\": 158,\n                    \"HasDistinct\": false,\n                    \"Items\": []\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": {\n        \"SettingsPos\": 162,\n        \"ListEnd\": 191,\n        \"Items\": [\n          {\n            \"SettingsPos\": 171,\n            \"Name\": {\n              \"Name\": \"fsync_after_insert\",\n              \"QuoteType\": 1,\n              \"NamePos\": 171,\n              \"NameEnd\": 189\n            },\n            \"Expr\": {\n              \"NumPos\": 190,\n              \"NumEnd\": 191,\n              \"Literal\": \"0\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": null\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_function_simple.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"OrReplace\": false,\n    \"IfNotExists\": false,\n    \"FunctionName\": {\n      \"Name\": \"linear_equation\",\n      \"QuoteType\": 1,\n      \"NamePos\": 16,\n      \"NameEnd\": 31\n    },\n    \"OnCluster\": null,\n    \"Params\": {\n      \"LeftParenPos\": 35,\n      \"RightParenPos\": 43,\n      \"Items\": {\n        \"ListPos\": 36,\n        \"ListEnd\": 43,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"x\",\n              \"QuoteType\": 1,\n              \"NamePos\": 36,\n              \"NameEnd\": 37\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"k\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 40\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"b\",\n              \"QuoteType\": 1,\n              \"NamePos\": 42,\n              \"NameEnd\": 43\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"ColumnArgList\": null\n    },\n    \"Expr\": {\n      \"LeftExpr\": {\n        \"LeftExpr\": {\n          \"Name\": \"k\",\n          \"QuoteType\": 1,\n          \"NamePos\": 48,\n          \"NameEnd\": 49\n        },\n        \"Operation\": \"*\",\n        \"RightExpr\": {\n          \"Name\": \"x\",\n          \"QuoteType\": 1,\n          \"NamePos\": 50,\n          \"NameEnd\": 51\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      },\n      \"Operation\": \"+\",\n      \"RightExpr\": {\n        \"Name\": \"b\",\n        \"QuoteType\": 1,\n        \"NamePos\": 54,\n        \"NameEnd\": 55\n      },\n      \"HasGlobal\": false,\n      \"HasNot\": false\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_live_view_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 101,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_live_view\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 29\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"Destination\": {\n      \"ToPos\": 46,\n      \"TableIdentifier\": {\n        \"Database\": null,\n        \"Table\": {\n          \"Name\": \"my_destination\",\n          \"QuoteType\": 1,\n          \"NamePos\": 49,\n          \"NameEnd\": 63\n        }\n      },\n      \"TableSchema\": null\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 63,\n      \"SchemaEnd\": 73,\n      \"Columns\": [\n        {\n          \"NamePos\": 64,\n          \"ColumnEnd\": 73,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 64,\n              \"NameEnd\": 66\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 67,\n              \"NameEnd\": 73\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"WithTimeout\": {\n      \"WithTimeoutPos\": 30,\n      \"Expr\": null,\n      \"Number\": {\n        \"NumPos\": 43,\n        \"NumEnd\": 45,\n        \"Literal\": \"10\",\n        \"Base\": 10\n      }\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 78,\n        \"StatementEnd\": 101,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 85,\n              \"NameEnd\": 87\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 88,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 93,\n              \"TableEnd\": 101,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"my_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 93,\n                  \"NameEnd\": 101\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 101,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_materialized_view_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 537,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"infra_bm\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 33\n      },\n      \"Table\": {\n        \"Name\": \"view_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 34,\n        \"NameEnd\": 43\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": {\n      \"OnPos\": 49,\n      \"Expr\": {\n        \"LiteralPos\": 61,\n        \"LiteralEnd\": 76,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": null,\n    \"HasEmpty\": false,\n    \"Destination\": {\n      \"ToPos\": 78,\n      \"TableIdentifier\": {\n        \"Database\": {\n          \"Name\": \"infra_bm\",\n          \"QuoteType\": 1,\n          \"NamePos\": 81,\n          \"NameEnd\": 89\n        },\n        \"Table\": {\n          \"Name\": \"table_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 90,\n          \"NameEnd\": 100\n        }\n      },\n      \"TableSchema\": {\n        \"SchemaPos\": 101,\n        \"SchemaEnd\": 203,\n        \"Columns\": [\n          {\n            \"NamePos\": 106,\n            \"ColumnEnd\": 122,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f1\",\n                \"QuoteType\": 3,\n                \"NamePos\": 106,\n                \"NameEnd\": 108\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"LeftParenPos\": 121,\n              \"RightParenPos\": 122,\n              \"Name\": {\n                \"Name\": \"DateTime64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 110,\n                \"NameEnd\": 120\n              },\n              \"Params\": [\n                {\n                  \"NumPos\": 121,\n                  \"NumEnd\": 122,\n                  \"Literal\": \"3\",\n                  \"Base\": 10\n                }\n              ]\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 129,\n            \"ColumnEnd\": 139,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f2\",\n                \"QuoteType\": 3,\n                \"NamePos\": 129,\n                \"NameEnd\": 131\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 133,\n                \"NameEnd\": 139\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 145,\n            \"ColumnEnd\": 155,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f3\",\n                \"QuoteType\": 3,\n                \"NamePos\": 145,\n                \"NameEnd\": 147\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 149,\n                \"NameEnd\": 155\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 161,\n            \"ColumnEnd\": 171,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f4\",\n                \"QuoteType\": 3,\n                \"NamePos\": 161,\n                \"NameEnd\": 163\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 165,\n                \"NameEnd\": 171\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 177,\n            \"ColumnEnd\": 187,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f5\",\n                \"QuoteType\": 3,\n                \"NamePos\": 177,\n                \"NameEnd\": 179\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 181,\n                \"NameEnd\": 187\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 193,\n            \"ColumnEnd\": 202,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f6\",\n                \"QuoteType\": 3,\n                \"NamePos\": 193,\n                \"NameEnd\": 195\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"Int64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 197,\n                \"NameEnd\": 202\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          }\n        ],\n        \"AliasTable\": null,\n        \"TableFunction\": null\n      }\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 208,\n        \"StatementEnd\": 537,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 215,\n              \"NameEnd\": 217\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 226,\n              \"NameEnd\": 228\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 237,\n                \"NameEnd\": 260\n              },\n              \"Params\": {\n                \"LeftParenPos\": 260,\n                \"RightParenPos\": 277,\n                \"Items\": {\n                  \"ListPos\": 261,\n                  \"ListEnd\": 276,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 261,\n                        \"NameEnd\": 271\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 274,\n                        \"LiteralEnd\": 276,\n                        \"Literal\": \"f3\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 284,\n              \"NameEnd\": 286\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 295,\n                \"NameEnd\": 318\n              },\n              \"Params\": {\n                \"LeftParenPos\": 318,\n                \"RightParenPos\": 335,\n                \"Items\": {\n                  \"ListPos\": 319,\n                  \"ListEnd\": 334,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 319,\n                        \"NameEnd\": 329\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 332,\n                        \"LiteralEnd\": 334,\n                        \"Literal\": \"f4\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 345,\n              \"NameEnd\": 347\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 356,\n                \"NameEnd\": 379\n              },\n              \"Params\": {\n                \"LeftParenPos\": 379,\n                \"RightParenPos\": 396,\n                \"Items\": {\n                  \"ListPos\": 380,\n                  \"ListEnd\": 395,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 380,\n                        \"NameEnd\": 390\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 393,\n                        \"LiteralEnd\": 395,\n                        \"Literal\": \"f5\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 404,\n              \"NameEnd\": 406\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractInt\",\n                \"QuoteType\": 1,\n                \"NamePos\": 412,\n                \"NameEnd\": 432\n              },\n              \"Params\": {\n                \"LeftParenPos\": 432,\n                \"RightParenPos\": 449,\n                \"Items\": {\n                  \"ListPos\": 433,\n                  \"ListEnd\": 448,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 433,\n                        \"NameEnd\": 443\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 446,\n                        \"LiteralEnd\": 448,\n                        \"Literal\": \"f6\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 1,\n              \"NamePos\": 454,\n              \"NameEnd\": 456\n            }\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 457,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 466,\n              \"TableEnd\": 486,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": {\n                  \"Name\": \"infra_bm\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 466,\n                  \"NameEnd\": 474\n                },\n                \"Table\": {\n                  \"Name\": \"table_name1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 475,\n                  \"NameEnd\": 486\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 486,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": {\n          \"WherePos\": 487,\n          \"Expr\": {\n            \"LeftExpr\": {\n              \"Fields\": [\n                {\n                  \"Name\": \"infra_bm\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 497,\n                  \"NameEnd\": 505\n                },\n                {\n                  \"Name\": \"table_name1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 506,\n                  \"NameEnd\": 517\n                },\n                {\n                  \"Name\": \"event\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 518,\n                  \"NameEnd\": 523\n                }\n              ]\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"LiteralPos\": 527,\n              \"LiteralEnd\": 537,\n              \"Literal\": \"test-event\"\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          }\n        },\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": {\n      \"LiteralPos\": 548,\n      \"LiteralEnd\": 565,\n      \"Literal\": \"Comment for table\"\n    },\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_materialized_view_with_comment_before_as.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 302,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 27\n      },\n      \"Table\": {\n        \"Name\": \"mv_with_comment\",\n        \"QuoteType\": 1,\n        \"NamePos\": 28,\n        \"NameEnd\": 43\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": null,\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": null,\n    \"HasEmpty\": false,\n    \"Destination\": {\n      \"ToPos\": 44,\n      \"TableIdentifier\": {\n        \"Database\": {\n          \"Name\": \"db\",\n          \"QuoteType\": 1,\n          \"NamePos\": 47,\n          \"NameEnd\": 49\n        },\n        \"Table\": {\n          \"Name\": \"dst_table\",\n          \"QuoteType\": 1,\n          \"NamePos\": 50,\n          \"NameEnd\": 59\n        }\n      },\n      \"TableSchema\": {\n        \"SchemaPos\": 60,\n        \"SchemaEnd\": 156,\n        \"Columns\": [\n          {\n            \"NamePos\": 67,\n            \"ColumnEnd\": 82,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"shop_id\",\n                \"QuoteType\": 3,\n                \"NamePos\": 67,\n                \"NameEnd\": 74\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"UInt64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 76,\n                \"NameEnd\": 82\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 89,\n            \"ColumnEnd\": 122,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"event_type\",\n                \"QuoteType\": 3,\n                \"NamePos\": 89,\n                \"NameEnd\": 99\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"LeftParenPos\": 116,\n              \"RightParenPos\": 122,\n              \"Name\": {\n                \"Name\": \"LowCardinality\",\n                \"QuoteType\": 1,\n                \"NamePos\": 101,\n                \"NameEnd\": 115\n              },\n              \"Params\": [\n                {\n                  \"Name\": {\n                    \"Name\": \"String\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 116,\n                    \"NameEnd\": 122\n                  }\n                }\n              ]\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 130,\n            \"ColumnEnd\": 154,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"created_at\",\n                \"QuoteType\": 3,\n                \"NamePos\": 130,\n                \"NameEnd\": 140\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"LeftParenPos\": 153,\n              \"RightParenPos\": 154,\n              \"Name\": {\n                \"Name\": \"DateTime64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 142,\n                \"NameEnd\": 152\n              },\n              \"Params\": [\n                {\n                  \"NumPos\": 153,\n                  \"NumEnd\": 154,\n                  \"Literal\": \"9\",\n                  \"Base\": 10\n                }\n              ]\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          }\n        ],\n        \"AliasTable\": null,\n        \"TableFunction\": null\n      }\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 234,\n        \"StatementEnd\": 302,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"shop_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 245,\n              \"NameEnd\": 252\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"event_type\",\n              \"QuoteType\": 1,\n              \"NamePos\": 258,\n              \"NameEnd\": 268\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"created_at\",\n              \"QuoteType\": 1,\n              \"NamePos\": 274,\n              \"NameEnd\": 284\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 285,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 290,\n              \"TableEnd\": 302,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": {\n                  \"Name\": \"db\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 290,\n                  \"NameEnd\": 292\n                },\n                \"Table\": {\n                  \"Name\": \"src_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 293,\n                  \"NameEnd\": 302\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 302,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": {\n      \"LiteralPos\": 167,\n      \"LiteralEnd\": 229,\n      \"Literal\": \"{\\\"blueprint_hash\\\":\\\"abc123\\\",\\\"timestamp\\\":\\\"2026-04-08T12:00:00Z\\\"}\"\n    },\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_materialized_view_with_definer.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 355,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"fresh_mv\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 33\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": null,\n    \"Refresh\": {\n      \"RefreshPos\": 34,\n      \"Frequency\": \"EVERY\",\n      \"Interval\": {\n        \"IntervalPos\": 0,\n        \"Expr\": {\n          \"NumPos\": 48,\n          \"NumEnd\": 49,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Unit\": {\n          \"Name\": \"HOUR\",\n          \"QuoteType\": 1,\n          \"NamePos\": 50,\n          \"NameEnd\": 54\n        }\n      },\n      \"Offset\": {\n        \"IntervalPos\": 0,\n        \"Expr\": {\n          \"NumPos\": 62,\n          \"NumEnd\": 64,\n          \"Literal\": \"10\",\n          \"Base\": 10\n        },\n        \"Unit\": {\n          \"Name\": \"MINUTE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 65,\n          \"NameEnd\": 71\n        }\n      }\n    },\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": true,\n    \"Engine\": null,\n    \"HasEmpty\": false,\n    \"Destination\": {\n      \"ToPos\": 79,\n      \"TableIdentifier\": {\n        \"Database\": null,\n        \"Table\": {\n          \"Name\": \"events_export\",\n          \"QuoteType\": 1,\n          \"NamePos\": 82,\n          \"NameEnd\": 95\n        }\n      },\n      \"TableSchema\": {\n        \"SchemaPos\": 96,\n        \"SchemaEnd\": 173,\n        \"Columns\": [\n          {\n            \"NamePos\": 103,\n            \"ColumnEnd\": 126,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"timestamp\",\n                \"QuoteType\": 3,\n                \"NamePos\": 103,\n                \"NameEnd\": 112\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"LeftParenPos\": 125,\n              \"RightParenPos\": 126,\n              \"Name\": {\n                \"Name\": \"DateTime64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 114,\n                \"NameEnd\": 124\n              },\n              \"Params\": [\n                {\n                  \"NumPos\": 125,\n                  \"NumEnd\": 126,\n                  \"Literal\": \"9\",\n                  \"Base\": 10\n                }\n              ]\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 134,\n            \"ColumnEnd\": 149,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"field_1\",\n                \"QuoteType\": 3,\n                \"NamePos\": 134,\n                \"NameEnd\": 141\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 143,\n                \"NameEnd\": 149\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 156,\n            \"ColumnEnd\": 171,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"field_2\",\n                \"QuoteType\": 3,\n                \"NamePos\": 156,\n                \"NameEnd\": 163\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 165,\n                \"NameEnd\": 171\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          }\n        ],\n        \"AliasTable\": null,\n        \"TableFunction\": null\n      }\n    },\n    \"SubQuery\": {\n      \"HasParen\": true,\n      \"Select\": {\n        \"SelectPos\": 218,\n        \"StatementEnd\": 355,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"timestamp\",\n              \"QuoteType\": 1,\n              \"NamePos\": 229,\n              \"NameEnd\": 238\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"field_1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 244,\n              \"NameEnd\": 251\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"field_2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 257,\n              \"NameEnd\": 264\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"FROM\",\n              \"QuoteType\": 1,\n              \"NamePos\": 266,\n              \"NameEnd\": 270\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"event_table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 271,\n              \"NameEnd\": 282\n            }\n          }\n        ],\n        \"From\": null,\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": {\n          \"WherePos\": 283,\n          \"Expr\": {\n            \"LeftExpr\": {\n              \"Name\": {\n                \"Name\": \"toStartOfHour\",\n                \"QuoteType\": 1,\n                \"NamePos\": 289,\n                \"NameEnd\": 302\n              },\n              \"Params\": {\n                \"LeftParenPos\": 302,\n                \"RightParenPos\": 312,\n                \"Items\": {\n                  \"ListPos\": 303,\n                  \"ListEnd\": 312,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"timestamp\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 303,\n                        \"NameEnd\": 312\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"Name\": {\n                \"Name\": \"toStartOfHour\",\n                \"QuoteType\": 1,\n                \"NamePos\": 316,\n                \"NameEnd\": 329\n              },\n              \"Params\": {\n                \"LeftParenPos\": 329,\n                \"RightParenPos\": 355,\n                \"Items\": {\n                  \"ListPos\": 330,\n                  \"ListEnd\": 354,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"LeftExpr\": {\n                          \"Name\": {\n                            \"Name\": \"now\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 330,\n                            \"NameEnd\": 333\n                          },\n                          \"Params\": {\n                            \"LeftParenPos\": 333,\n                            \"RightParenPos\": 334,\n                            \"Items\": {\n                              \"ListPos\": 334,\n                              \"ListEnd\": 334,\n                              \"HasDistinct\": false,\n                              \"Items\": []\n                            },\n                            \"ColumnArgList\": null\n                          }\n                        },\n                        \"Operation\": \"-\",\n                        \"RightExpr\": {\n                          \"Name\": {\n                            \"Name\": \"toIntervalHour\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 338,\n                            \"NameEnd\": 352\n                          },\n                          \"Params\": {\n                            \"LeftParenPos\": 352,\n                            \"RightParenPos\": 354,\n                            \"Items\": {\n                              \"ListPos\": 353,\n                              \"ListEnd\": 354,\n                              \"HasDistinct\": false,\n                              \"Items\": [\n                                {\n                                  \"Expr\": {\n                                    \"NumPos\": 353,\n                                    \"NumEnd\": 354,\n                                    \"Literal\": \"1\",\n                                    \"Base\": 10\n                                  },\n                                  \"Alias\": null\n                                }\n                              ]\n                            },\n                            \"ColumnArgList\": null\n                          }\n                        },\n                        \"HasGlobal\": false,\n                        \"HasNot\": false\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          }\n        },\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": {\n      \"LiteralPos\": 367,\n      \"LiteralEnd\": 379,\n      \"Literal\": \"Test comment\"\n    },\n    \"Definer\": {\n      \"Name\": \"default\",\n      \"QuoteType\": 1,\n      \"NamePos\": 185,\n      \"NameEnd\": 192\n    },\n    \"SQLSecurity\": \"DEFINER\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 460,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 29\n      },\n      \"Table\": {\n        \"Name\": \"t0\",\n        \"QuoteType\": 1,\n        \"NamePos\": 30,\n        \"NameEnd\": 32\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": {\n      \"OnPos\": 33,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 44,\n        \"NameEnd\": 59\n      }\n    },\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": {\n      \"EnginePos\": 60,\n      \"EngineEnd\": 190,\n      \"Name\": \"ReplicatedAggregatingMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 99,\n        \"RightParenPos\": 150,\n        \"Items\": {\n          \"ListPos\": 101,\n          \"ListEnd\": 149,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 101,\n                \"LiteralEnd\": 136,\n                \"Literal\": \"/clickhouse/{layer}-{shard}/test/t0\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 140,\n                \"LiteralEnd\": 149,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 152,\n        \"Expr\": {\n          \"ListPos\": 165,\n          \"ListEnd\": 176,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMM\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 165,\n                  \"NameEnd\": 173\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 173,\n                  \"RightParenPos\": 176,\n                  \"Items\": {\n                    \"ListPos\": 174,\n                    \"ListEnd\": 176,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f0\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 174,\n                          \"NameEnd\": 176\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 178,\n        \"ListEnd\": 190,\n        \"Items\": [\n          {\n            \"OrderPos\": 178,\n            \"Expr\": {\n              \"LeftParenPos\": 187,\n              \"RightParenPos\": 190,\n              \"Items\": {\n                \"ListPos\": 188,\n                \"ListEnd\": 190,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 188,\n                      \"NameEnd\": 190\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"HasEmpty\": false,\n    \"Destination\": null,\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 204,\n        \"StatementEnd\": 460,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 211,\n              \"NameEnd\": 213\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 214,\n              \"NameEnd\": 216\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 217,\n              \"NameEnd\": 219\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"coalesce\",\n                \"QuoteType\": 1,\n                \"NamePos\": 220,\n                \"NameEnd\": 228\n              },\n              \"Params\": {\n                \"LeftParenPos\": 228,\n                \"RightParenPos\": 234,\n                \"Items\": {\n                  \"ListPos\": 229,\n                  \"ListEnd\": 234,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"f0\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 229,\n                        \"NameEnd\": 231\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"Name\": \"f1\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 232,\n                        \"NameEnd\": 234\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f333\",\n              \"QuoteType\": 1,\n              \"NamePos\": 239,\n              \"NameEnd\": 243\n            }\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 244,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 253,\n              \"TableEnd\": 447,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Expr\": {\n                  \"HasParen\": true,\n                  \"Select\": {\n                    \"SelectPos\": 254,\n                    \"StatementEnd\": 433,\n                    \"With\": null,\n                    \"Top\": null,\n                    \"HasDistinct\": false,\n                    \"DistinctOn\": null,\n                    \"SelectItems\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f0\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 270,\n                          \"NameEnd\": 272\n                        },\n                        \"Modifiers\": [],\n                        \"Alias\": null\n                      },\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f1\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 273,\n                          \"NameEnd\": 275\n                        },\n                        \"Modifiers\": [],\n                        \"Alias\": null\n                      },\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f2\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 276,\n                          \"NameEnd\": 278\n                        },\n                        \"Modifiers\": [],\n                        \"Alias\": null\n                      },\n                      {\n                        \"Expr\": {\n                          \"Function\": {\n                            \"Name\": {\n                              \"Name\": \"ROW_NUMBER\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 289,\n                              \"NameEnd\": 299\n                            },\n                            \"Params\": {\n                              \"LeftParenPos\": 299,\n                              \"RightParenPos\": 300,\n                              \"Items\": {\n                                \"ListPos\": 300,\n                                \"ListEnd\": 300,\n                                \"HasDistinct\": false,\n                                \"Items\": []\n                              },\n                              \"ColumnArgList\": null\n                            }\n                          },\n                          \"OverPos\": 302,\n                          \"OverExpr\": {\n                            \"LeftParenPos\": 306,\n                            \"RightParenPos\": 347,\n                            \"WindowName\": null,\n                            \"PartitionBy\": {\n                              \"PartitionPos\": 306,\n                              \"Expr\": {\n                                \"ListPos\": 320,\n                                \"ListEnd\": 322,\n                                \"HasDistinct\": false,\n                                \"Items\": [\n                                  {\n                                    \"Expr\": {\n                                      \"Name\": \"f0\",\n                                      \"QuoteType\": 1,\n                                      \"NamePos\": 320,\n                                      \"NameEnd\": 322\n                                    },\n                                    \"Alias\": null\n                                  }\n                                ]\n                              }\n                            },\n                            \"OrderBy\": {\n                              \"OrderPos\": 323,\n                              \"ListEnd\": 346,\n                              \"Items\": [\n                                {\n                                  \"OrderPos\": 323,\n                                  \"Expr\": {\n                                    \"Name\": {\n                                      \"Name\": \"coalesce\",\n                                      \"QuoteType\": 1,\n                                      \"NamePos\": 332,\n                                      \"NameEnd\": 340\n                                    },\n                                    \"Params\": {\n                                      \"LeftParenPos\": 340,\n                                      \"RightParenPos\": 346,\n                                      \"Items\": {\n                                        \"ListPos\": 341,\n                                        \"ListEnd\": 346,\n                                        \"HasDistinct\": false,\n                                        \"Items\": [\n                                          {\n                                            \"Expr\": {\n                                              \"Name\": \"f1\",\n                                              \"QuoteType\": 1,\n                                              \"NamePos\": 341,\n                                              \"NameEnd\": 343\n                                            },\n                                            \"Alias\": null\n                                          },\n                                          {\n                                            \"Expr\": {\n                                              \"Name\": \"f2\",\n                                              \"QuoteType\": 1,\n                                              \"NamePos\": 344,\n                                              \"NameEnd\": 346\n                                            },\n                                            \"Alias\": null\n                                          }\n                                        ]\n                                      },\n                                      \"ColumnArgList\": null\n                                    }\n                                  },\n                                  \"Alias\": null,\n                                  \"Direction\": \"\",\n                                  \"Fill\": null\n                                }\n                              ],\n                              \"Interpolate\": null\n                            },\n                            \"Frame\": null\n                          }\n                        },\n                        \"Modifiers\": [],\n                        \"Alias\": {\n                          \"Name\": \"rn\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 352,\n                          \"NameEnd\": 354\n                        }\n                      }\n                    ],\n                    \"From\": {\n                      \"FromPos\": 360,\n                      \"Expr\": {\n                        \"Table\": {\n                          \"TablePos\": 365,\n                          \"TableEnd\": 371,\n                          \"Alias\": null,\n                          \"Expr\": {\n                            \"Database\": {\n                              \"Name\": \"test\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 365,\n                              \"NameEnd\": 369\n                            },\n                            \"Table\": {\n                              \"Name\": \"t\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 370,\n                              \"NameEnd\": 371\n                            }\n                          },\n                          \"HasFinal\": false\n                        },\n                        \"StatementEnd\": 371,\n                        \"SampleRatio\": null,\n                        \"HasFinal\": false\n                      }\n                    },\n                    \"Window\": null,\n                    \"Prewhere\": null,\n                    \"Where\": {\n                      \"WherePos\": 377,\n                      \"Expr\": {\n                        \"LeftExpr\": {\n                          \"LeftExpr\": {\n                            \"Name\": \"f3\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 383,\n                            \"NameEnd\": 385\n                          },\n                          \"Operation\": \"IN\",\n                          \"RightExpr\": {\n                            \"LeftParenPos\": 389,\n                            \"RightParenPos\": 410,\n                            \"Items\": {\n                              \"ListPos\": 391,\n                              \"ListEnd\": 409,\n                              \"HasDistinct\": false,\n                              \"Items\": [\n                                {\n                                  \"Expr\": {\n                                    \"LiteralPos\": 391,\n                                    \"LiteralEnd\": 394,\n                                    \"Literal\": \"foo\"\n                                  },\n                                  \"Alias\": null\n                                },\n                                {\n                                  \"Expr\": {\n                                    \"LiteralPos\": 398,\n                                    \"LiteralEnd\": 401,\n                                    \"Literal\": \"bar\"\n                                  },\n                                  \"Alias\": null\n                                },\n                                {\n                                  \"Expr\": {\n                                    \"LiteralPos\": 405,\n                                    \"LiteralEnd\": 409,\n                                    \"Literal\": \"test\"\n                                  },\n                                  \"Alias\": null\n                                }\n                              ]\n                            },\n                            \"ColumnArgList\": null\n                          },\n                          \"HasGlobal\": false,\n                          \"HasNot\": false\n                        },\n                        \"Operation\": \"AND\",\n                        \"RightExpr\": {\n                          \"LeftExpr\": {\n                            \"Name\": \"env\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 423,\n                            \"NameEnd\": 426\n                          },\n                          \"Operation\": \"=\",\n                          \"RightExpr\": {\n                            \"LiteralPos\": 429,\n                            \"LiteralEnd\": 433,\n                            \"Literal\": \"test\"\n                          },\n                          \"HasGlobal\": false,\n                          \"HasNot\": false\n                        },\n                        \"HasGlobal\": false,\n                        \"HasNot\": false\n                      }\n                    },\n                    \"GroupBy\": null,\n                    \"WithTotal\": false,\n                    \"Having\": null,\n                    \"OrderBy\": null,\n                    \"LimitBy\": null,\n                    \"Limit\": null,\n                    \"Settings\": null,\n                    \"Format\": null,\n                    \"UnionAll\": null,\n                    \"UnionDistinct\": null,\n                    \"Except\": null\n                  }\n                },\n                \"AliasPos\": 444,\n                \"Alias\": {\n                  \"Name\": \"tmp\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 444,\n                  \"NameEnd\": 447\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 447,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": {\n          \"WherePos\": 448,\n          \"Expr\": {\n            \"LeftExpr\": {\n              \"Name\": \"rn\",\n              \"QuoteType\": 1,\n              \"NamePos\": 454,\n              \"NameEnd\": 456\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"NumPos\": 459,\n              \"NumEnd\": 460,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          }\n        },\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": true,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_materialized_view_with_gcs.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 206,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"database_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 38\n      },\n      \"Table\": {\n        \"Name\": \"view_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 39,\n        \"NameEnd\": 48\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": null,\n    \"Refresh\": {\n      \"RefreshPos\": 57,\n      \"Frequency\": \"EVERY\",\n      \"Interval\": {\n        \"IntervalPos\": 0,\n        \"Expr\": {\n          \"NumPos\": 71,\n          \"NumEnd\": 72,\n          \"Literal\": \"5\",\n          \"Base\": 10\n        },\n        \"Unit\": {\n          \"Name\": \"MINUTE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 73,\n          \"NameEnd\": 79\n        }\n      },\n      \"Offset\": null\n    },\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": null,\n    \"HasEmpty\": false,\n    \"Destination\": {\n      \"ToPos\": 80,\n      \"TableIdentifier\": {\n        \"Database\": {\n          \"Name\": \"database_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 83,\n          \"NameEnd\": 96\n        },\n        \"Table\": {\n          \"Name\": \"table_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 97,\n          \"NameEnd\": 107\n        }\n      },\n      \"TableSchema\": null\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 119,\n        \"StatementEnd\": 206,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"*\",\n              \"QuoteType\": 0,\n              \"NamePos\": 126,\n              \"NameEnd\": 126\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 128,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 133,\n              \"TableEnd\": 206,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"gcs\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 133,\n                  \"NameEnd\": 136\n                },\n                \"Args\": {\n                  \"LeftParenPos\": 136,\n                  \"RightParenPos\": 206,\n                  \"Args\": [\n                    {\n                      \"Name\": \"gcs_creds\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 137,\n                      \"NameEnd\": 146\n                    },\n                    {\n                      \"NamePos\": 147,\n                      \"Name\": {\n                        \"Name\": \"url\",\n                        \"QuoteType\": 0,\n                        \"NamePos\": 147,\n                        \"NameEnd\": 150\n                      },\n                      \"Value\": {\n                        \"LiteralPos\": 152,\n                        \"LiteralEnd\": 205,\n                        \"Literal\": \"https://storage.googleapis.com/some-bucket/some-path/\"\n                      }\n                    }\n                  ]\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 206,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_materialized_view_with_refresh.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 302,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"fresh_mv\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 33\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": null,\n    \"Refresh\": {\n      \"RefreshPos\": 34,\n      \"Frequency\": \"EVERY\",\n      \"Interval\": {\n        \"IntervalPos\": 0,\n        \"Expr\": {\n          \"NumPos\": 48,\n          \"NumEnd\": 49,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Unit\": {\n          \"Name\": \"HOUR\",\n          \"QuoteType\": 1,\n          \"NamePos\": 50,\n          \"NameEnd\": 54\n        }\n      },\n      \"Offset\": {\n        \"IntervalPos\": 0,\n        \"Expr\": {\n          \"NumPos\": 62,\n          \"NumEnd\": 64,\n          \"Literal\": \"10\",\n          \"Base\": 10\n        },\n        \"Unit\": {\n          \"Name\": \"MINUTE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 65,\n          \"NameEnd\": 71\n        }\n      }\n    },\n    \"RandomizeFor\": {\n      \"IntervalPos\": 0,\n      \"Expr\": {\n        \"NumPos\": 86,\n        \"NumEnd\": 87,\n        \"Literal\": \"1\",\n        \"Base\": 10\n      },\n      \"Unit\": {\n        \"Name\": \"SECOND\",\n        \"QuoteType\": 1,\n        \"NamePos\": 88,\n        \"NameEnd\": 94\n      }\n    },\n    \"DependsOn\": [\n      {\n        \"Database\": null,\n        \"Table\": {\n          \"Name\": \"table_v5\",\n          \"QuoteType\": 1,\n          \"NamePos\": 107,\n          \"NameEnd\": 115\n        }\n      }\n    ],\n    \"Settings\": {\n      \"SettingsPos\": 116,\n      \"ListEnd\": 199,\n      \"Items\": [\n        {\n          \"SettingsPos\": 129,\n          \"Name\": {\n            \"Name\": \"randomize_for\",\n            \"QuoteType\": 1,\n            \"NamePos\": 129,\n            \"NameEnd\": 142\n          },\n          \"Expr\": {\n            \"NumPos\": 145,\n            \"NumEnd\": 146,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 152,\n          \"Name\": {\n            \"Name\": \"randomize_offset\",\n            \"QuoteType\": 1,\n            \"NamePos\": 152,\n            \"NameEnd\": 168\n          },\n          \"Expr\": {\n            \"NumPos\": 171,\n            \"NumEnd\": 173,\n            \"Literal\": \"10\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 179,\n          \"Name\": {\n            \"Name\": \"randomize_period\",\n            \"QuoteType\": 1,\n            \"NamePos\": 179,\n            \"NameEnd\": 195\n          },\n          \"Expr\": {\n            \"NumPos\": 198,\n            \"NumEnd\": 199,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        }\n      ]\n    },\n    \"HasAppend\": true,\n    \"Engine\": null,\n    \"HasEmpty\": true,\n    \"Destination\": {\n      \"ToPos\": 207,\n      \"TableIdentifier\": {\n        \"Database\": null,\n        \"Table\": {\n          \"Name\": \"target_table_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 210,\n          \"NameEnd\": 227\n        }\n      },\n      \"TableSchema\": null\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 237,\n        \"StatementEnd\": 302,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"field_1\",\n              \"QuoteType\": 3,\n              \"NamePos\": 249,\n              \"NameEnd\": 256\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"field_2\",\n              \"QuoteType\": 3,\n              \"NamePos\": 264,\n              \"NameEnd\": 271\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"field_3\",\n              \"QuoteType\": 3,\n              \"NamePos\": 279,\n              \"NameEnd\": 286\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"FROM\",\n              \"QuoteType\": 1,\n              \"NamePos\": 289,\n              \"NameEnd\": 293\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"table_v5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 294,\n              \"NameEnd\": 302\n            }\n          }\n        ],\n        \"From\": null,\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_mv_with_not_op.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 559,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"infra_bm\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 33\n      },\n      \"Table\": {\n        \"Name\": \"view_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 34,\n        \"NameEnd\": 43\n      }\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": {\n      \"OnPos\": 48,\n      \"Expr\": {\n        \"LiteralPos\": 60,\n        \"LiteralEnd\": 75,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": null,\n    \"HasEmpty\": false,\n    \"Destination\": {\n      \"ToPos\": 77,\n      \"TableIdentifier\": {\n        \"Database\": {\n          \"Name\": \"infra_bm\",\n          \"QuoteType\": 1,\n          \"NamePos\": 80,\n          \"NameEnd\": 88\n        },\n        \"Table\": {\n          \"Name\": \"table_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 89,\n          \"NameEnd\": 99\n        }\n      },\n      \"TableSchema\": {\n        \"SchemaPos\": 100,\n        \"SchemaEnd\": 197,\n        \"Columns\": [\n          {\n            \"NamePos\": 105,\n            \"ColumnEnd\": 121,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f1\",\n                \"QuoteType\": 3,\n                \"NamePos\": 105,\n                \"NameEnd\": 107\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"LeftParenPos\": 120,\n              \"RightParenPos\": 121,\n              \"Name\": {\n                \"Name\": \"DateTime64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 109,\n                \"NameEnd\": 119\n              },\n              \"Params\": [\n                {\n                  \"NumPos\": 120,\n                  \"NumEnd\": 121,\n                  \"Literal\": \"3\",\n                  \"Base\": 10\n                }\n              ]\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 127,\n            \"ColumnEnd\": 137,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f2\",\n                \"QuoteType\": 3,\n                \"NamePos\": 127,\n                \"NameEnd\": 129\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 131,\n                \"NameEnd\": 137\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 142,\n            \"ColumnEnd\": 152,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f3\",\n                \"QuoteType\": 3,\n                \"NamePos\": 142,\n                \"NameEnd\": 144\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 146,\n                \"NameEnd\": 152\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 157,\n            \"ColumnEnd\": 167,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f4\",\n                \"QuoteType\": 3,\n                \"NamePos\": 157,\n                \"NameEnd\": 159\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 161,\n                \"NameEnd\": 167\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 172,\n            \"ColumnEnd\": 182,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f5\",\n                \"QuoteType\": 3,\n                \"NamePos\": 172,\n                \"NameEnd\": 174\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 176,\n                \"NameEnd\": 182\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          },\n          {\n            \"NamePos\": 187,\n            \"ColumnEnd\": 196,\n            \"Name\": {\n              \"Ident\": {\n                \"Name\": \"f6\",\n                \"QuoteType\": 3,\n                \"NamePos\": 187,\n                \"NameEnd\": 189\n              },\n              \"DotIdent\": null\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"Int64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 191,\n                \"NameEnd\": 196\n              }\n            },\n            \"NotNull\": null,\n            \"Nullable\": null,\n            \"DefaultExpr\": null,\n            \"MaterializedExpr\": null,\n            \"AliasExpr\": null,\n            \"Codec\": null,\n            \"TTL\": null,\n            \"Comment\": null,\n            \"CompressionCodec\": null\n          }\n        ],\n        \"AliasTable\": null,\n        \"TableFunction\": null\n      }\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 202,\n        \"StatementEnd\": 559,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 209,\n              \"NameEnd\": 211\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 220,\n              \"NameEnd\": 222\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 231,\n                \"NameEnd\": 254\n              },\n              \"Params\": {\n                \"LeftParenPos\": 254,\n                \"RightParenPos\": 271,\n                \"Items\": {\n                  \"ListPos\": 255,\n                  \"ListEnd\": 270,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 255,\n                        \"NameEnd\": 265\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 268,\n                        \"LiteralEnd\": 270,\n                        \"Literal\": \"f3\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 276,\n              \"NameEnd\": 278\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 287,\n                \"NameEnd\": 310\n              },\n              \"Params\": {\n                \"LeftParenPos\": 310,\n                \"RightParenPos\": 327,\n                \"Items\": {\n                  \"ListPos\": 311,\n                  \"ListEnd\": 326,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 311,\n                        \"NameEnd\": 321\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 324,\n                        \"LiteralEnd\": 326,\n                        \"Literal\": \"f4\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 332,\n              \"NameEnd\": 334\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractString\",\n                \"QuoteType\": 1,\n                \"NamePos\": 343,\n                \"NameEnd\": 366\n              },\n              \"Params\": {\n                \"LeftParenPos\": 366,\n                \"RightParenPos\": 383,\n                \"Items\": {\n                  \"ListPos\": 367,\n                  \"ListEnd\": 382,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 367,\n                        \"NameEnd\": 377\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 380,\n                        \"LiteralEnd\": 382,\n                        \"Literal\": \"f5\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 388,\n              \"NameEnd\": 390\n            }\n          },\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"visitParamExtractInt\",\n                \"QuoteType\": 1,\n                \"NamePos\": 399,\n                \"NameEnd\": 419\n              },\n              \"Params\": {\n                \"LeftParenPos\": 419,\n                \"RightParenPos\": 436,\n                \"Items\": {\n                  \"ListPos\": 420,\n                  \"ListEnd\": 435,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"properties\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 420,\n                        \"NameEnd\": 430\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 433,\n                        \"LiteralEnd\": 435,\n                        \"Literal\": \"f6\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 1,\n              \"NamePos\": 441,\n              \"NameEnd\": 443\n            }\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 444,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 449,\n              \"TableEnd\": 469,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": {\n                  \"Name\": \"infra_bm\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 449,\n                  \"NameEnd\": 457\n                },\n                \"Table\": {\n                  \"Name\": \"table_name1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 458,\n                  \"NameEnd\": 469\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 469,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": {\n          \"WherePos\": 470,\n          \"Expr\": {\n            \"LeftExpr\": {\n              \"LeftExpr\": {\n                \"LeftExpr\": {\n                  \"Fields\": [\n                    {\n                      \"Name\": \"infra_bm\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 476,\n                      \"NameEnd\": 484\n                    },\n                    {\n                      \"Name\": \"table_name1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 485,\n                      \"NameEnd\": 496\n                    },\n                    {\n                      \"Name\": \"event\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 497,\n                      \"NameEnd\": 502\n                    }\n                  ]\n                },\n                \"Operation\": \"=\",\n                \"RightExpr\": {\n                  \"LiteralPos\": 506,\n                  \"LiteralEnd\": 516,\n                  \"Literal\": \"test-event\"\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Operation\": \"AND\",\n              \"RightExpr\": {\n                \"UnaryPos\": 526,\n                \"Kind\": \"NOT\",\n                \"Expr\": {\n                  \"Name\": {\n                    \"Name\": \"isZeroOrNull\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 530,\n                    \"NameEnd\": 542\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 542,\n                    \"RightParenPos\": 545,\n                    \"Items\": {\n                      \"ListPos\": 543,\n                      \"ListEnd\": 545,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Name\": \"f2\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 543,\n                            \"NameEnd\": 545\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Operation\": \"AND\",\n            \"RightExpr\": {\n              \"LeftExpr\": {\n                \"LeftExpr\": {\n                  \"Name\": \"f6\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 551,\n                  \"NameEnd\": 553\n                },\n                \"Operation\": \"-\",\n                \"RightExpr\": {\n                  \"NumPos\": 554,\n                  \"NumEnd\": 555,\n                  \"Literal\": \"2\",\n                  \"Base\": 10\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Operation\": \"\\u003e\",\n              \"RightExpr\": {\n                \"NumPos\": 558,\n                \"NumEnd\": 559,\n                \"Literal\": \"0\",\n                \"Base\": 10\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          }\n        },\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_mv_with_order_by.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 135,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_mv\",\n        \"QuoteType\": 1,\n        \"NamePos\": 39,\n        \"NameEnd\": 46\n      }\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": null,\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": {\n      \"EnginePos\": 47,\n      \"EngineEnd\": 106,\n      \"Name\": \"ReplacingMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 74,\n        \"RightParenPos\": 75,\n        \"Items\": {\n          \"ListPos\": 75,\n          \"ListEnd\": 75,\n          \"HasDistinct\": false,\n          \"Items\": []\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": {\n        \"PrimaryPos\": 77,\n        \"Expr\": {\n          \"LeftParenPos\": 89,\n          \"RightParenPos\": 92,\n          \"Items\": {\n            \"ListPos\": 90,\n            \"ListEnd\": 92,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"id\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 90,\n                  \"NameEnd\": 92\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      },\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 94,\n        \"ListEnd\": 106,\n        \"Items\": [\n          {\n            \"OrderPos\": 94,\n            \"Expr\": {\n              \"LeftParenPos\": 103,\n              \"RightParenPos\": 106,\n              \"Items\": {\n                \"ListPos\": 104,\n                \"ListEnd\": 106,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"id\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 104,\n                      \"NameEnd\": 106\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"HasEmpty\": false,\n    \"Destination\": null,\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 111,\n        \"StatementEnd\": 135,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"*\",\n              \"QuoteType\": 0,\n              \"NamePos\": 118,\n              \"NameEnd\": 118\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 120,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 125,\n              \"TableEnd\": 135,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"test_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 125,\n                  \"NameEnd\": 135\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 135,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  },\n  {\n    \"CreatePos\": 138,\n    \"StatementEnd\": 259,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_mv\",\n        \"QuoteType\": 1,\n        \"NamePos\": 177,\n        \"NameEnd\": 184\n      }\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": null,\n    \"Refresh\": null,\n    \"RandomizeFor\": null,\n    \"DependsOn\": null,\n    \"Settings\": null,\n    \"HasAppend\": false,\n    \"Engine\": {\n      \"EnginePos\": 185,\n      \"EngineEnd\": 230,\n      \"Name\": \"ReplacingMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 212,\n        \"RightParenPos\": 213,\n        \"Items\": {\n          \"ListPos\": 213,\n          \"ListEnd\": 213,\n          \"HasDistinct\": false,\n          \"Items\": []\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": {\n        \"PrimaryPos\": 215,\n        \"Expr\": {\n          \"LeftParenPos\": 227,\n          \"RightParenPos\": 230,\n          \"Items\": {\n            \"ListPos\": 228,\n            \"ListEnd\": 230,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"id\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 228,\n                  \"NameEnd\": 230\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      },\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": null\n    },\n    \"HasEmpty\": false,\n    \"Destination\": null,\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 235,\n        \"StatementEnd\": 259,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"*\",\n              \"QuoteType\": 0,\n              \"NamePos\": 242,\n              \"NameEnd\": 242\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 244,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 249,\n              \"TableEnd\": 259,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"test_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 249,\n                  \"NameEnd\": 259\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 259,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    },\n    \"Populate\": false,\n    \"Comment\": null,\n    \"Definer\": null,\n    \"SQLSecurity\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_named_collection_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 158,\n    \"Name\": {\n      \"Name\": \"servercore_s3_config\",\n      \"QuoteType\": 1,\n      \"NamePos\": 38,\n      \"NameEnd\": 58\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": null,\n    \"Params\": [\n      {\n        \"ParamPos\": 62,\n        \"Name\": {\n          \"Name\": \"url\",\n          \"QuoteType\": 1,\n          \"NamePos\": 62,\n          \"NameEnd\": 65\n        },\n        \"Value\": {\n          \"LiteralPos\": 69,\n          \"LiteralEnd\": 94,\n          \"Literal\": \"http://local-minio:9000/*\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      },\n      {\n        \"ParamPos\": 97,\n        \"Name\": {\n          \"Name\": \"access_key_id\",\n          \"QuoteType\": 1,\n          \"NamePos\": 97,\n          \"NameEnd\": 110\n        },\n        \"Value\": {\n          \"LiteralPos\": 114,\n          \"LiteralEnd\": 124,\n          \"Literal\": \"minioadmin\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      },\n      {\n        \"ParamPos\": 127,\n        \"Name\": {\n          \"Name\": \"secret_access_key\",\n          \"QuoteType\": 1,\n          \"NamePos\": 127,\n          \"NameEnd\": 144\n        },\n        \"Value\": {\n          \"LiteralPos\": 148,\n          \"LiteralEnd\": 158,\n          \"Literal\": \"minioadmin\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_named_collection_simple.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 72,\n    \"Name\": {\n      \"Name\": \"my_collection\",\n      \"QuoteType\": 1,\n      \"NamePos\": 24,\n      \"NameEnd\": 37\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": null,\n    \"Params\": [\n      {\n        \"ParamPos\": 41,\n        \"Name\": {\n          \"Name\": \"key1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 41,\n          \"NameEnd\": 45\n        },\n        \"Value\": {\n          \"LiteralPos\": 49,\n          \"LiteralEnd\": 55,\n          \"Literal\": \"value1\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      },\n      {\n        \"ParamPos\": 58,\n        \"Name\": {\n          \"Name\": \"key2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 58,\n          \"NameEnd\": 62\n        },\n        \"Value\": {\n          \"LiteralPos\": 66,\n          \"LiteralEnd\": 72,\n          \"Literal\": \"value2\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_named_collection_with_cluster.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 153,\n    \"Name\": {\n      \"Name\": \"my_collection\",\n      \"QuoteType\": 1,\n      \"NamePos\": 38,\n      \"NameEnd\": 51\n    },\n    \"IfNotExists\": true,\n    \"OnCluster\": {\n      \"OnPos\": 52,\n      \"Expr\": {\n        \"Name\": \"my_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 63,\n        \"NameEnd\": 73\n      }\n    },\n    \"Params\": [\n      {\n        \"ParamPos\": 77,\n        \"Name\": {\n          \"Name\": \"key1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 77,\n          \"NameEnd\": 81\n        },\n        \"Value\": {\n          \"LiteralPos\": 85,\n          \"LiteralEnd\": 91,\n          \"Literal\": \"value1\"\n        },\n        \"Overridable\": true,\n        \"NotOverridable\": false\n      },\n      {\n        \"ParamPos\": 106,\n        \"Name\": {\n          \"Name\": \"key2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 106,\n          \"NameEnd\": 110\n        },\n        \"Value\": {\n          \"LiteralPos\": 114,\n          \"LiteralEnd\": 120,\n          \"Literal\": \"value2\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": true\n      },\n      {\n        \"ParamPos\": 139,\n        \"Name\": {\n          \"Name\": \"key3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 139,\n          \"NameEnd\": 143\n        },\n        \"Value\": {\n          \"LiteralPos\": 147,\n          \"LiteralEnd\": 153,\n          \"Literal\": \"value3\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_named_collection_with_overridable.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 145,\n    \"Name\": {\n      \"Name\": \"test_collection\",\n      \"QuoteType\": 1,\n      \"NamePos\": 24,\n      \"NameEnd\": 39\n    },\n    \"IfNotExists\": false,\n    \"OnCluster\": null,\n    \"Params\": [\n      {\n        \"ParamPos\": 43,\n        \"Name\": {\n          \"Name\": \"url\",\n          \"QuoteType\": 1,\n          \"NamePos\": 43,\n          \"NameEnd\": 46\n        },\n        \"Value\": {\n          \"LiteralPos\": 50,\n          \"LiteralEnd\": 68,\n          \"Literal\": \"http://example.com\"\n        },\n        \"Overridable\": true,\n        \"NotOverridable\": false\n      },\n      {\n        \"ParamPos\": 83,\n        \"Name\": {\n          \"Name\": \"access_key\",\n          \"QuoteType\": 1,\n          \"NamePos\": 83,\n          \"NameEnd\": 93\n        },\n        \"Value\": {\n          \"LiteralPos\": 97,\n          \"LiteralEnd\": 103,\n          \"Literal\": \"key123\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": true\n      },\n      {\n        \"ParamPos\": 122,\n        \"Name\": {\n          \"Name\": \"secret_key\",\n          \"QuoteType\": 1,\n          \"NamePos\": 122,\n          \"NameEnd\": 132\n        },\n        \"Value\": {\n          \"LiteralPos\": 136,\n          \"LiteralEnd\": 145,\n          \"Literal\": \"secret456\"\n        },\n        \"Overridable\": false,\n        \"NotOverridable\": false\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_or_replace.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 122,\n    \"StatementEnd\": 361,\n    \"OrReplace\": true,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 160,\n        \"NameEnd\": 164\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 165,\n        \"NameEnd\": 177\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 178,\n      \"SchemaEnd\": 246,\n      \"Columns\": [\n        {\n          \"NamePos\": 184,\n          \"ColumnEnd\": 193,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 184,\n              \"NameEnd\": 186\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 187,\n              \"NameEnd\": 193\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 199,\n          \"ColumnEnd\": 223,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 199,\n              \"NameEnd\": 201\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 202,\n              \"NameEnd\": 208\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 209,\n            \"RightParenPos\": 223,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 215,\n              \"NameEnd\": 219\n            },\n            \"Level\": {\n              \"NumPos\": 219,\n              \"NumEnd\": 221,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 229,\n          \"ColumnEnd\": 243,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 229,\n              \"NameEnd\": 231\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 240,\n            \"RightParenPos\": 243,\n            \"Name\": {\n              \"Name\": \"VARCHAR\",\n              \"QuoteType\": 1,\n              \"NamePos\": 232,\n              \"NameEnd\": 239\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 240,\n                \"NumEnd\": 243,\n                \"Literal\": \"255\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 248,\n      \"EngineEnd\": 361,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": {\n        \"PrimaryPos\": 267,\n        \"Expr\": {\n          \"LeftParenPos\": 279,\n          \"RightParenPos\": 290,\n          \"Items\": {\n            \"ListPos\": 280,\n            \"ListEnd\": 290,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"f0\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 280,\n                  \"NameEnd\": 282\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"f1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 284,\n                  \"NameEnd\": 286\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"f2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 288,\n                  \"NameEnd\": 290\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      },\n      \"PartitionBy\": {\n        \"PartitionPos\": 292,\n        \"Expr\": {\n          \"ListPos\": 305,\n          \"ListEnd\": 318,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMMDD\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 305,\n                  \"NameEnd\": 315\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 315,\n                  \"RightParenPos\": 318,\n                  \"Items\": {\n                    \"ListPos\": 316,\n                    \"ListEnd\": 318,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f1\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 316,\n                          \"NameEnd\": 318\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 320,\n        \"ListEnd\": 345,\n        \"Items\": [\n          {\n            \"TTLPos\": 320,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"f1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 324,\n                \"NameEnd\": 326\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 329,\n                \"Expr\": {\n                  \"NumPos\": 338,\n                  \"NumEnd\": 339,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 340,\n                  \"NameEnd\": 345\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 346,\n        \"ListEnd\": 361,\n        \"Items\": [\n          {\n            \"OrderPos\": 346,\n            \"Expr\": {\n              \"LeftParenPos\": 355,\n              \"RightParenPos\": 361,\n              \"Items\": {\n                \"ListPos\": 356,\n                \"ListEnd\": 361,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 356,\n                      \"NameEnd\": 358\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 359,\n                      \"NameEnd\": 361\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": {\n      \"LiteralPos\": 372,\n      \"LiteralEnd\": 389,\n      \"Literal\": \"Comment for table\"\n    }\n  },\n  {\n    \"CreatePos\": 393,\n    \"StatementEnd\": 508,\n    \"OrReplace\": true,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_view\",\n        \"QuoteType\": 1,\n        \"NamePos\": 430,\n        \"NameEnd\": 437\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 437,\n      \"SchemaEnd\": 462,\n      \"Columns\": [\n        {\n          \"NamePos\": 438,\n          \"ColumnEnd\": 449,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"col1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 438,\n              \"NameEnd\": 442\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 443,\n              \"NameEnd\": 449\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 451,\n          \"ColumnEnd\": 462,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"col2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 451,\n              \"NameEnd\": 455\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 456,\n              \"NameEnd\": 462\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Comment\": null,\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 467,\n        \"StatementEnd\": 508,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 478,\n              \"NameEnd\": 480\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 486,\n              \"NameEnd\": 490\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 491,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 500,\n              \"TableEnd\": 508,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"my_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 500,\n                  \"NameEnd\": 508\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 508,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  },\n  {\n    \"CreatePos\": 511,\n    \"OrReplace\": true,\n    \"IfNotExists\": true,\n    \"FunctionName\": {\n      \"Name\": \"my_function\",\n      \"QuoteType\": 1,\n      \"NamePos\": 552,\n      \"NameEnd\": 563\n    },\n    \"OnCluster\": null,\n    \"Params\": {\n      \"LeftParenPos\": 567,\n      \"RightParenPos\": 572,\n      \"Items\": {\n        \"ListPos\": 568,\n        \"ListEnd\": 572,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"x\",\n              \"QuoteType\": 1,\n              \"NamePos\": 568,\n              \"NameEnd\": 569\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"y\",\n              \"QuoteType\": 1,\n              \"NamePos\": 571,\n              \"NameEnd\": 572\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"ColumnArgList\": null\n    },\n    \"Expr\": {\n      \"LeftExpr\": {\n        \"Name\": \"x\",\n        \"QuoteType\": 1,\n        \"NamePos\": 577,\n        \"NameEnd\": 578\n      },\n      \"Operation\": \"+\",\n      \"RightExpr\": {\n        \"Name\": \"y\",\n        \"QuoteType\": 1,\n        \"NamePos\": 581,\n        \"NameEnd\": 582\n      },\n      \"HasGlobal\": false,\n      \"HasNot\": false\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_role.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 22,\n    \"StatementEnd\": 42,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 34,\n          \"NameEnd\": 42\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 44,\n    \"StatementEnd\": 85,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 56,\n          \"NameEnd\": 64\n        },\n        \"Scope\": null,\n        \"OnCluster\": {\n          \"OnPos\": 65,\n          \"Expr\": {\n            \"Name\": \"cluster_1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 76,\n            \"NameEnd\": 85\n          }\n        }\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 87,\n    \"StatementEnd\": 117,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 99,\n          \"NameEnd\": 107\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 109,\n          \"NameEnd\": 117\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 119,\n    \"StatementEnd\": 170,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 131,\n          \"NameEnd\": 139\n        },\n        \"Scope\": null,\n        \"OnCluster\": {\n          \"OnPos\": 140,\n          \"Expr\": {\n            \"Name\": \"cluster_1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 151,\n            \"NameEnd\": 160\n          }\n        }\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 162,\n          \"NameEnd\": 170\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 172,\n    \"StatementEnd\": 244,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 184,\n          \"NameEnd\": 192\n        },\n        \"Scope\": null,\n        \"OnCluster\": {\n          \"OnPos\": 193,\n          \"Expr\": {\n            \"Name\": \"cluster_1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 204,\n            \"NameEnd\": 213\n          }\n        }\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 215,\n          \"NameEnd\": 223\n        },\n        \"Scope\": null,\n        \"OnCluster\": {\n          \"OnPos\": 224,\n          \"Expr\": {\n            \"Name\": \"cluster_2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 235,\n            \"NameEnd\": 244\n          }\n        }\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 246,\n    \"StatementEnd\": 280,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 258,\n          \"NameEnd\": 266\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [],\n        \"Modifier\": {\n          \"Name\": \"NONE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 276,\n          \"NameEnd\": 280\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 282,\n    \"StatementEnd\": 328,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 294,\n          \"NameEnd\": 302\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 312,\n              \"NameEnd\": 319\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 321,\n              \"LiteralEnd\": 328,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 331,\n    \"StatementEnd\": 385,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r3_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 343,\n          \"NameEnd\": 351\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 361,\n              \"NameEnd\": 377\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 378,\n              \"NumEnd\": 385,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 387,\n    \"StatementEnd\": 445,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r4_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 399,\n          \"NameEnd\": 407\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 417,\n              \"NameEnd\": 433\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MIN\",\n              \"QuoteType\": 1,\n              \"NamePos\": 434,\n              \"NameEnd\": 437\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 438,\n              \"NumEnd\": 445,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 447,\n    \"StatementEnd\": 505,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r5_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 459,\n          \"NameEnd\": 467\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 477,\n              \"NameEnd\": 493\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MAX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 494,\n              \"NameEnd\": 497\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 498,\n              \"NumEnd\": 505,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 507,\n    \"StatementEnd\": 559,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r6_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 519,\n          \"NameEnd\": 527\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 537,\n              \"NameEnd\": 553\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"CONST\",\n          \"QuoteType\": 1,\n          \"NamePos\": 554,\n          \"NameEnd\": 559\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 561,\n    \"StatementEnd\": 616,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r7_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 573,\n          \"NameEnd\": 581\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 591,\n              \"NameEnd\": 607\n            },\n            \"Operation\": \"\",\n            \"Value\": null\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"WRITABLE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 608,\n          \"NameEnd\": 616\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 618,\n    \"StatementEnd\": 702,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r8_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 630,\n          \"NameEnd\": 638\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 648,\n              \"NameEnd\": 664\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 665,\n              \"NumEnd\": 672,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MIN\",\n              \"QuoteType\": 1,\n              \"NamePos\": 673,\n              \"NameEnd\": 676\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 677,\n              \"NumEnd\": 684,\n              \"Literal\": \"4000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MAX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 685,\n              \"NameEnd\": 688\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 689,\n              \"NumEnd\": 696,\n              \"Literal\": \"6000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"CONST\",\n          \"QuoteType\": 1,\n          \"NamePos\": 697,\n          \"NameEnd\": 702\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 704,\n    \"StatementEnd\": 786,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r9_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 716,\n          \"NameEnd\": 724\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 734,\n              \"NameEnd\": 741\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 743,\n              \"LiteralEnd\": 750,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 753,\n              \"NameEnd\": 769\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 770,\n              \"NumEnd\": 777,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"WRITABLE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 778,\n          \"NameEnd\": 786\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 788,\n    \"StatementEnd\": 818,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 800,\n          \"NameEnd\": 808\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 810,\n          \"NameEnd\": 818\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 820,\n    \"StatementEnd\": 860,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 832,\n          \"NameEnd\": 840\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"readonly\",\n              \"QuoteType\": 1,\n              \"NamePos\": 850,\n              \"NameEnd\": 858\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 859,\n              \"NumEnd\": 860,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 862,\n    \"StatementEnd\": 908,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 874,\n          \"NameEnd\": 882\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 892,\n              \"NameEnd\": 899\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 901,\n              \"LiteralEnd\": 908,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 911,\n    \"StatementEnd\": 998,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r3_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 923,\n          \"NameEnd\": 931\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 941,\n              \"NameEnd\": 957\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 958,\n              \"NumEnd\": 965,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MIN\",\n              \"QuoteType\": 1,\n              \"NamePos\": 966,\n              \"NameEnd\": 969\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 970,\n              \"NumEnd\": 977,\n              \"Literal\": \"4000000\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"MAX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 978,\n              \"NameEnd\": 981\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"NumPos\": 982,\n              \"NumEnd\": 989,\n              \"Literal\": \"6000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": {\n          \"Name\": \"WRITABLE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 990,\n          \"NameEnd\": 998\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 1000,\n    \"StatementEnd\": 1085,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r4_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1012,\n          \"NameEnd\": 1020\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1030,\n              \"NameEnd\": 1037\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 1039,\n              \"LiteralEnd\": 1046,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1049,\n              \"NameEnd\": 1065\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 1066,\n              \"NumEnd\": 1073,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"readonly\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1075,\n              \"NameEnd\": 1083\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 1084,\n              \"NumEnd\": 1085,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 1087,\n    \"StatementEnd\": 1121,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r5_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1099,\n          \"NameEnd\": 1107\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [],\n        \"Modifier\": {\n          \"Name\": \"NONE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1117,\n          \"NameEnd\": 1121\n        }\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 1123,\n    \"StatementEnd\": 1146,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1135,\n          \"NameEnd\": 1143\n        },\n        \"Scope\": {\n          \"LiteralPos\": 1145,\n          \"LiteralEnd\": 1146,\n          \"Literal\": \"%\"\n        },\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1149,\n    \"StatementEnd\": 1183,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"RoleNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1161,\n          \"NameEnd\": 1169\n        },\n        \"Scope\": {\n          \"LiteralPos\": 1171,\n          \"LiteralEnd\": 1183,\n          \"Literal\": \"%.myhost.com\"\n        },\n        \"OnCluster\": null\n      }\n    ],\n    \"AccessStorageType\": null,\n    \"Settings\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_as_remote_function.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 62,\n    \"StatementEnd\": 222,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_remote\",\n        \"QuoteType\": 1,\n        \"NamePos\": 75,\n        \"NameEnd\": 86\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 87,\n      \"SchemaEnd\": 137,\n      \"Columns\": [\n        {\n          \"NamePos\": 93,\n          \"ColumnEnd\": 102,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 93,\n              \"NameEnd\": 95\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 96,\n              \"NameEnd\": 102\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 108,\n          \"ColumnEnd\": 119,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 108,\n              \"NameEnd\": 112\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 113,\n              \"NameEnd\": 119\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 125,\n          \"ColumnEnd\": 136,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 125,\n              \"NameEnd\": 130\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Int32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 131,\n              \"NameEnd\": 136\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": null,\n    \"SubQuery\": null,\n    \"TableFunction\": {\n      \"Name\": {\n        \"Name\": \"remoteSecure\",\n        \"QuoteType\": 1,\n        \"NamePos\": 142,\n        \"NameEnd\": 154\n      },\n      \"Args\": {\n        \"LeftParenPos\": 154,\n        \"RightParenPos\": 222,\n        \"Args\": [\n          {\n            \"LiteralPos\": 156,\n            \"LiteralEnd\": 172,\n            \"Literal\": \"host.example.com\"\n          },\n          {\n            \"LiteralPos\": 176,\n            \"LiteralEnd\": 185,\n            \"Literal\": \"source_db\"\n          },\n          {\n            \"LiteralPos\": 189,\n            \"LiteralEnd\": 201,\n            \"Literal\": \"source_table\"\n          },\n          {\n            \"LiteralPos\": 205,\n            \"LiteralEnd\": 209,\n            \"Literal\": \"user\"\n          },\n          {\n            \"LiteralPos\": 213,\n            \"LiteralEnd\": 221,\n            \"Literal\": \"password\"\n          }\n        ]\n      }\n    },\n    \"HasTemporary\": false,\n    \"Comment\": null\n  },\n  {\n    \"CreatePos\": 261,\n    \"StatementEnd\": 353,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 274,\n        \"NameEnd\": 284\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 285,\n      \"SchemaEnd\": 308,\n      \"Columns\": [\n        {\n          \"NamePos\": 286,\n          \"ColumnEnd\": 295,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 286,\n              \"NameEnd\": 288\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 289,\n              \"NameEnd\": 295\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 297,\n          \"ColumnEnd\": 308,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 297,\n              \"NameEnd\": 301\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 302,\n              \"NameEnd\": 308\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": null,\n    \"SubQuery\": null,\n    \"TableFunction\": {\n      \"Name\": {\n        \"Name\": \"remote\",\n        \"QuoteType\": 1,\n        \"NamePos\": 313,\n        \"NameEnd\": 319\n      },\n      \"Args\": {\n        \"LeftParenPos\": 319,\n        \"RightParenPos\": 353,\n        \"Args\": [\n          {\n            \"LiteralPos\": 321,\n            \"LiteralEnd\": 330,\n            \"Literal\": \"localhost\"\n          },\n          {\n            \"LiteralPos\": 334,\n            \"LiteralEnd\": 336,\n            \"Literal\": \"db\"\n          },\n          {\n            \"LiteralPos\": 340,\n            \"LiteralEnd\": 352,\n            \"Literal\": \"source_table\"\n          }\n        ]\n      }\n    },\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 122,\n    \"StatementEnd\": 774,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 149,\n        \"NameEnd\": 153\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 154,\n        \"NameEnd\": 166\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 167,\n      \"SchemaEnd\": 656,\n      \"Columns\": [\n        {\n          \"NamePos\": 173,\n          \"ColumnEnd\": 182,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 173,\n              \"NameEnd\": 175\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 176,\n              \"NameEnd\": 182\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 188,\n          \"ColumnEnd\": 212,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 188,\n              \"NameEnd\": 190\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 191,\n              \"NameEnd\": 197\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 198,\n            \"RightParenPos\": 212,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 204,\n              \"NameEnd\": 208\n            },\n            \"Level\": {\n              \"NumPos\": 208,\n              \"NumEnd\": 210,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 218,\n          \"ColumnEnd\": 232,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 218,\n              \"NameEnd\": 220\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 229,\n            \"RightParenPos\": 232,\n            \"Name\": {\n              \"Name\": \"VARCHAR\",\n              \"QuoteType\": 1,\n              \"NamePos\": 221,\n              \"NameEnd\": 228\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 229,\n                \"NumEnd\": 232,\n                \"Literal\": \"255\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 239,\n          \"ColumnEnd\": 250,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 239,\n              \"NameEnd\": 241\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 242,\n              \"NameEnd\": 250\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 256,\n          \"ColumnEnd\": 267,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 256,\n              \"NameEnd\": 258\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 259,\n              \"NameEnd\": 267\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 273,\n          \"ColumnEnd\": 293,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 273,\n              \"NameEnd\": 275\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 280,\n            \"RightParenPos\": 293,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 276,\n              \"NameEnd\": 279\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 280,\n                  \"NameEnd\": 286\n                }\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 287,\n                  \"NameEnd\": 293\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 300,\n          \"ColumnEnd\": 309,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 1,\n              \"NamePos\": 300,\n              \"NameEnd\": 302\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 303,\n              \"NameEnd\": 309\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 315,\n          \"ColumnEnd\": 450,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f7\",\n              \"QuoteType\": 1,\n              \"NamePos\": 315,\n              \"NameEnd\": 317\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 335,\n            \"RightParenPos\": 450,\n            \"Name\": {\n              \"Name\": \"Nested\",\n              \"QuoteType\": 1,\n              \"NamePos\": 318,\n              \"NameEnd\": 324\n            },\n            \"Columns\": [\n              {\n                \"NamePos\": 335,\n                \"ColumnEnd\": 345,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"f70\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 335,\n                    \"NameEnd\": 338\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"UInt32\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 339,\n                    \"NameEnd\": 345\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              },\n              {\n                \"NamePos\": 355,\n                \"ColumnEnd\": 365,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"f71\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 355,\n                    \"NameEnd\": 358\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"UInt32\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 359,\n                    \"NameEnd\": 365\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              },\n              {\n                \"NamePos\": 375,\n                \"ColumnEnd\": 387,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"f72\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 375,\n                    \"NameEnd\": 378\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"DateTime\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 379,\n                    \"NameEnd\": 387\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              },\n              {\n                \"NamePos\": 397,\n                \"ColumnEnd\": 406,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"f73\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 397,\n                    \"NameEnd\": 400\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"Int64\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 401,\n                    \"NameEnd\": 406\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              },\n              {\n                \"NamePos\": 416,\n                \"ColumnEnd\": 425,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"f74\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 416,\n                    \"NameEnd\": 419\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"Int64\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 420,\n                    \"NameEnd\": 425\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              },\n              {\n                \"NamePos\": 435,\n                \"ColumnEnd\": 445,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"f75\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 435,\n                    \"NameEnd\": 438\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"String\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 439,\n                    \"NameEnd\": 445\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 457,\n          \"ColumnEnd\": 481,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 457,\n              \"NameEnd\": 459\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 460,\n              \"NameEnd\": 468\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"Name\": {\n              \"Name\": \"now\",\n              \"QuoteType\": 1,\n              \"NamePos\": 477,\n              \"NameEnd\": 480\n            },\n            \"Params\": {\n              \"LeftParenPos\": 480,\n              \"RightParenPos\": 481,\n              \"Items\": {\n                \"ListPos\": 481,\n                \"ListEnd\": 481,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 488,\n          \"ColumnEnd\": 529,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f9\",\n              \"QuoteType\": 1,\n              \"NamePos\": 488,\n              \"NameEnd\": 490\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 491,\n              \"NameEnd\": 497\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": {\n            \"Name\": {\n              \"Name\": \"toString\",\n              \"QuoteType\": 1,\n              \"NamePos\": 511,\n              \"NameEnd\": 519\n            },\n            \"Params\": {\n              \"LeftParenPos\": 519,\n              \"RightParenPos\": 529,\n              \"Items\": {\n                \"ListPos\": 520,\n                \"ListEnd\": 528,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Object\": {\n                        \"Name\": \"f7\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 520,\n                        \"NameEnd\": 522\n                      },\n                      \"Params\": {\n                        \"LeftBracketPos\": 522,\n                        \"RightBracketPos\": 528,\n                        \"Items\": {\n                          \"ListPos\": 524,\n                          \"ListEnd\": 527,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 524,\n                                \"LiteralEnd\": 527,\n                                \"Literal\": \"f70\"\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        }\n                      }\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 536,\n          \"ColumnEnd\": 556,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f10\",\n              \"QuoteType\": 1,\n              \"NamePos\": 536,\n              \"NameEnd\": 539\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 540,\n              \"NameEnd\": 546\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": {\n            \"Name\": \"f11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 553,\n            \"NameEnd\": 556\n          },\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 562,\n          \"ColumnEnd\": 653,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f12\",\n              \"QuoteType\": 1,\n              \"NamePos\": 562,\n              \"NameEnd\": 565\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"JSON\",\n              \"QuoteType\": 1,\n              \"NamePos\": 566,\n              \"NameEnd\": 570\n            },\n            \"Options\": {\n              \"LParen\": 571,\n              \"RParen\": 653,\n              \"Items\": [\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": {\n                    \"NumPos\": 589,\n                    \"NumEnd\": 591,\n                    \"Literal\": \"10\",\n                    \"Base\": 10\n                  },\n                  \"Column\": null\n                },\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": {\n                    \"NumPos\": 611,\n                    \"NumEnd\": 612,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  },\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                },\n                {\n                  \"SkipPath\": {\n                    \"Idents\": [\n                      {\n                        \"Name\": \"a\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 619,\n                        \"NameEnd\": 620\n                      }\n                    ]\n                  },\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                },\n                {\n                  \"SkipPath\": {\n                    \"Idents\": [\n                      {\n                        \"Name\": \"a\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 627,\n                        \"NameEnd\": 628\n                      },\n                      {\n                        \"Name\": \"b\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 629,\n                        \"NameEnd\": 630\n                      },\n                      {\n                        \"Name\": \"c\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 631,\n                        \"NameEnd\": 632\n                      }\n                    ]\n                  },\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                },\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": {\n                    \"LiteralPos\": 647,\n                    \"LiteralEnd\": 652,\n                    \"Literal\": \"hello\"\n                  },\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                }\n              ]\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 658,\n      \"EngineEnd\": 774,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": {\n        \"PrimaryPos\": 677,\n        \"Expr\": {\n          \"LeftParenPos\": 689,\n          \"RightParenPos\": 700,\n          \"Items\": {\n            \"ListPos\": 690,\n            \"ListEnd\": 700,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"f0\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 690,\n                  \"NameEnd\": 692\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"f1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 694,\n                  \"NameEnd\": 696\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"f2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 698,\n                  \"NameEnd\": 700\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      },\n      \"PartitionBy\": {\n        \"PartitionPos\": 702,\n        \"Expr\": {\n          \"ListPos\": 715,\n          \"ListEnd\": 728,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMMDD\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 715,\n                  \"NameEnd\": 725\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 725,\n                  \"RightParenPos\": 728,\n                  \"Items\": {\n                    \"ListPos\": 726,\n                    \"ListEnd\": 728,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f3\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 726,\n                          \"NameEnd\": 728\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 730,\n        \"ListEnd\": 755,\n        \"Items\": [\n          {\n            \"TTLPos\": 730,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"f3\",\n                \"QuoteType\": 1,\n                \"NamePos\": 734,\n                \"NameEnd\": 736\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 739,\n                \"Expr\": {\n                  \"NumPos\": 748,\n                  \"NumEnd\": 749,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 750,\n                  \"NameEnd\": 755\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 756,\n        \"ListEnd\": 774,\n        \"Items\": [\n          {\n            \"OrderPos\": 756,\n            \"Expr\": {\n              \"LeftParenPos\": 765,\n              \"RightParenPos\": 774,\n              \"Items\": {\n                \"ListPos\": 766,\n                \"ListEnd\": 774,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 766,\n                      \"NameEnd\": 768\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 769,\n                      \"NameEnd\": 771\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f3\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 772,\n                      \"NameEnd\": 774\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": {\n      \"LiteralPos\": 785,\n      \"LiteralEnd\": 802,\n      \"Literal\": \"Comment for table\"\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_codec_no_args.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 0,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"shark_attacks\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 26\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 27,\n      \"SchemaEnd\": 72,\n      \"Columns\": [\n        {\n          \"NamePos\": 33,\n          \"ColumnEnd\": 70,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"timestamp\",\n              \"QuoteType\": 1,\n              \"NamePos\": 33,\n              \"NameEnd\": 42\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 43,\n              \"NameEnd\": 51\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 52,\n            \"RightParenPos\": 70,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"DoubleDelta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 58,\n              \"NameEnd\": 69\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": null,\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_json_typehints.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 139,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 14\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 15,\n      \"SchemaEnd\": 103,\n      \"Columns\": [\n        {\n          \"NamePos\": 21,\n          \"ColumnEnd\": 101,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"j\",\n              \"QuoteType\": 1,\n              \"NamePos\": 21,\n              \"NameEnd\": 22\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"JSON\",\n              \"QuoteType\": 1,\n              \"NamePos\": 23,\n              \"NameEnd\": 27\n            },\n            \"Options\": {\n              \"LParen\": 28,\n              \"RParen\": 101,\n              \"Items\": [\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": {\n                    \"Path\": {\n                      \"Idents\": [\n                        {\n                          \"Name\": \"message\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 28,\n                          \"NameEnd\": 35\n                        }\n                      ]\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"String\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 36,\n                        \"NameEnd\": 42\n                      }\n                    }\n                  }\n                },\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": {\n                    \"Path\": {\n                      \"Idents\": [\n                        {\n                          \"Name\": \"a\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 44,\n                          \"NameEnd\": 45\n                        },\n                        {\n                          \"Name\": \"b\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 46,\n                          \"NameEnd\": 47\n                        }\n                      ]\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"UInt64\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 48,\n                        \"NameEnd\": 54\n                      }\n                    }\n                  }\n                },\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": {\n                    \"NumPos\": 74,\n                    \"NumEnd\": 75,\n                    \"Literal\": \"0\",\n                    \"Base\": 10\n                  },\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                },\n                {\n                  \"SkipPath\": {\n                    \"Idents\": [\n                      {\n                        \"Name\": \"x\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 82,\n                        \"NameEnd\": 83\n                      }\n                    ]\n                  },\n                  \"SkipRegex\": null,\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                },\n                {\n                  \"SkipPath\": null,\n                  \"SkipRegex\": {\n                    \"LiteralPos\": 98,\n                    \"LiteralEnd\": 100,\n                    \"Literal\": \"re\"\n                  },\n                  \"MaxDynamicPaths\": null,\n                  \"MaxDynamicTypes\": null,\n                  \"Column\": null\n                }\n              ]\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 105,\n      \"EngineEnd\": 139,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 124,\n        \"ListEnd\": 139,\n        \"Items\": [\n          {\n            \"OrderPos\": 124,\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"tuple\",\n                \"QuoteType\": 1,\n                \"NamePos\": 133,\n                \"NameEnd\": 138\n              },\n              \"Params\": {\n                \"LeftParenPos\": 138,\n                \"RightParenPos\": 139,\n                \"Items\": {\n                  \"ListPos\": 139,\n                  \"ListEnd\": 139,\n                  \"HasDistinct\": false,\n                  \"Items\": []\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_codec_delta.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 812,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 37\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 38,\n      \"SchemaEnd\": 375,\n      \"Columns\": [\n        {\n          \"NamePos\": 42,\n          \"ColumnEnd\": 74,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 42,\n              \"NameEnd\": 44\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 46,\n              \"NameEnd\": 52\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 53,\n            \"RightParenPos\": 74,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 59,\n              \"NameEnd\": 64\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 70\n            },\n            \"Level\": {\n              \"NumPos\": 70,\n              \"NumEnd\": 72,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 78,\n          \"ColumnEnd\": 107,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"api_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 78,\n              \"NameEnd\": 84\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 86,\n              \"NameEnd\": 92\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 93,\n            \"RightParenPos\": 107,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 99,\n              \"NameEnd\": 103\n            },\n            \"Level\": {\n              \"NumPos\": 103,\n              \"NumEnd\": 105,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 111,\n          \"ColumnEnd\": 150,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"app_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 111,\n              \"NameEnd\": 117\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 119,\n              \"NameEnd\": 125\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 126,\n            \"RightParenPos\": 150,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 132,\n              \"NameEnd\": 137\n            },\n            \"TypeLevel\": {\n              \"NumPos\": 137,\n              \"NumEnd\": 139,\n              \"Literal\": \"9\",\n              \"Base\": 10\n            },\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 142,\n              \"NameEnd\": 146\n            },\n            \"Level\": {\n              \"NumPos\": 146,\n              \"NumEnd\": 148,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 154,\n          \"ColumnEnd\": 199,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"device_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 154,\n              \"NameEnd\": 163\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 165,\n              \"NameEnd\": 171\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 172,\n            \"RightParenPos\": 199,\n            \"Type\": {\n              \"Name\": \"DoubleDelta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 178,\n              \"NameEnd\": 189\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 191,\n              \"NameEnd\": 195\n            },\n            \"Level\": {\n              \"NumPos\": 195,\n              \"NumEnd\": 197,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 203,\n          \"ColumnEnd\": 237,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"guage\",\n              \"QuoteType\": 3,\n              \"NamePos\": 203,\n              \"NameEnd\": 208\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Float64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 210,\n              \"NameEnd\": 217\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 218,\n            \"RightParenPos\": 237,\n            \"Type\": {\n              \"Name\": \"Gorilla\",\n              \"QuoteType\": 1,\n              \"NamePos\": 224,\n              \"NameEnd\": 231\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 233,\n              \"NameEnd\": 236\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 241,\n          \"ColumnEnd\": 270,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"value\",\n              \"QuoteType\": 3,\n              \"NamePos\": 241,\n              \"NameEnd\": 246\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 248,\n              \"NameEnd\": 254\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 255,\n            \"RightParenPos\": 270,\n            \"Type\": {\n              \"Name\": \"T64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 261,\n              \"NameEnd\": 264\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 266,\n              \"NameEnd\": 269\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 274,\n          \"ColumnEnd\": 313,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"timestamp\",\n              \"QuoteType\": 3,\n              \"NamePos\": 274,\n              \"NameEnd\": 283\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 296,\n            \"RightParenPos\": 297,\n            \"Name\": {\n              \"Name\": \"DateTime64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 285,\n              \"NameEnd\": 295\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 296,\n                \"NumEnd\": 297,\n                \"Literal\": \"9\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 299,\n            \"RightParenPos\": 313,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 305,\n              \"NameEnd\": 309\n            },\n            \"Level\": {\n              \"NumPos\": 309,\n              \"NumEnd\": 311,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"IndexPos\": 316,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"timestamp_index\",\n              \"QuoteType\": 1,\n              \"NamePos\": 322,\n              \"NameEnd\": 337\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"LeftParenPos\": 337,\n              \"RightParenPos\": 347,\n              \"Items\": {\n                \"ListPos\": 338,\n                \"ListEnd\": 347,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"timestamp\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 338,\n                      \"NameEnd\": 347\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"Name\": {\n              \"Name\": \"minmax\",\n              \"QuoteType\": 1,\n              \"NamePos\": 354,\n              \"NameEnd\": 360\n            }\n          },\n          \"Granularity\": {\n            \"NumPos\": 373,\n            \"NumEnd\": 374,\n            \"Literal\": \"4\",\n            \"Base\": 10\n          }\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 377,\n      \"EngineEnd\": 812,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 405,\n        \"RightParenPos\": 437,\n        \"Items\": {\n          \"ListPos\": 407,\n          \"ListEnd\": 436,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 407,\n                \"LiteralEnd\": 423,\n                \"Literal\": \"/root/test_local\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 427,\n                \"LiteralEnd\": 436,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 439,\n        \"Expr\": {\n          \"ListPos\": 452,\n          \"ListEnd\": 477,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toStartOfHour\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 452,\n                  \"NameEnd\": 465\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 465,\n                  \"RightParenPos\": 477,\n                  \"Items\": {\n                    \"ListPos\": 467,\n                    \"ListEnd\": 476,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 3,\n                          \"NamePos\": 467,\n                          \"NameEnd\": 476\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 535,\n        \"ListEnd\": 626,\n        \"Items\": [\n          {\n            \"TTLPos\": 535,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": {\n                  \"Name\": \"toStartOfHour\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 539,\n                  \"NameEnd\": 552\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 552,\n                  \"RightParenPos\": 564,\n                  \"Items\": {\n                    \"ListPos\": 554,\n                    \"ListEnd\": 563,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 3,\n                          \"NamePos\": 554,\n                          \"NameEnd\": 563\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 568,\n                \"Expr\": {\n                  \"NumPos\": 577,\n                  \"NumEnd\": 578,\n                  \"Literal\": \"7\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"DAY\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 579,\n                  \"NameEnd\": 582\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          },\n          {\n            \"TTLPos\": 535,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": {\n                  \"Name\": \"toStartOfHour\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 583,\n                  \"NameEnd\": 596\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 596,\n                  \"RightParenPos\": 608,\n                  \"Items\": {\n                    \"ListPos\": 598,\n                    \"ListEnd\": 607,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 3,\n                          \"NamePos\": 598,\n                          \"NameEnd\": 607\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 612,\n                \"Expr\": {\n                  \"NumPos\": 621,\n                  \"NumEnd\": 622,\n                  \"Literal\": \"2\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"DAY\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 623,\n                  \"NameEnd\": 626\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": {\n        \"SettingsPos\": 627,\n        \"ListEnd\": 812,\n        \"Items\": [\n          {\n            \"SettingsPos\": 636,\n            \"Name\": {\n              \"Name\": \"execute_merges_on_single_replica_time_threshold\",\n              \"QuoteType\": 1,\n              \"NamePos\": 636,\n              \"NameEnd\": 683\n            },\n            \"Expr\": {\n              \"NumPos\": 684,\n              \"NumEnd\": 688,\n              \"Literal\": \"1200\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 690,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 690,\n              \"NameEnd\": 707\n            },\n            \"Expr\": {\n              \"NumPos\": 708,\n              \"NumEnd\": 713,\n              \"Literal\": \"16384\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 715,\n            \"Name\": {\n              \"Name\": \"max_bytes_to_merge_at_max_space_in_pool\",\n              \"QuoteType\": 1,\n              \"NamePos\": 715,\n              \"NameEnd\": 754\n            },\n            \"Expr\": {\n              \"NumPos\": 755,\n              \"NumEnd\": 766,\n              \"Literal\": \"64424509440\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 768,\n            \"Name\": {\n              \"Name\": \"storage_policy\",\n              \"QuoteType\": 1,\n              \"NamePos\": 768,\n              \"NameEnd\": 782\n            },\n            \"Expr\": {\n              \"LiteralPos\": 784,\n              \"LiteralEnd\": 788,\n              \"Literal\": \"main\"\n            }\n          },\n          {\n            \"SettingsPos\": 791,\n            \"Name\": {\n              \"Name\": \"ttl_only_drop_parts\",\n              \"QuoteType\": 1,\n              \"NamePos\": 791,\n              \"NameEnd\": 810\n            },\n            \"Expr\": {\n              \"NumPos\": 811,\n              \"NumEnd\": 812,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 479,\n        \"ListEnd\": 533,\n        \"Items\": [\n          {\n            \"OrderPos\": 479,\n            \"Expr\": {\n              \"LeftParenPos\": 488,\n              \"RightParenPos\": 533,\n              \"Items\": {\n                \"ListPos\": 489,\n                \"ListEnd\": 532,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"toUnixTimestamp64Nano\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 489,\n                        \"NameEnd\": 510\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 510,\n                        \"RightParenPos\": 522,\n                        \"Items\": {\n                          \"ListPos\": 512,\n                          \"ListEnd\": 521,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"Name\": \"timestamp\",\n                                \"QuoteType\": 3,\n                                \"NamePos\": 512,\n                                \"NameEnd\": 521\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"api_id\",\n                      \"QuoteType\": 3,\n                      \"NamePos\": 526,\n                      \"NameEnd\": 532\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_enum_fields.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 448,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t0\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 15\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 16,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 42\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 43,\n      \"SchemaEnd\": 233,\n      \"Columns\": [\n        {\n          \"NamePos\": 50,\n          \"ColumnEnd\": 176,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"method\",\n              \"QuoteType\": 3,\n              \"NamePos\": 50,\n              \"NameEnd\": 56\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Enum8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 58,\n              \"NameEnd\": 63\n            },\n            \"ListPos\": 65,\n            \"ListEnd\": 160,\n            \"Values\": [\n              {\n                \"Name\": {\n                  \"LiteralPos\": 65,\n                  \"LiteralEnd\": 68,\n                  \"Literal\": \"GET\"\n                },\n                \"Value\": {\n                  \"NumPos\": 70,\n                  \"NumEnd\": 71,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 75,\n                  \"LiteralEnd\": 79,\n                  \"Literal\": \"POST\"\n                },\n                \"Value\": {\n                  \"NumPos\": 81,\n                  \"NumEnd\": 82,\n                  \"Literal\": \"2\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 85,\n                  \"LiteralEnd\": 89,\n                  \"Literal\": \"HEAD\"\n                },\n                \"Value\": {\n                  \"NumPos\": 91,\n                  \"NumEnd\": 92,\n                  \"Literal\": \"3\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 95,\n                  \"LiteralEnd\": 98,\n                  \"Literal\": \"PUT\"\n                },\n                \"Value\": {\n                  \"NumPos\": 100,\n                  \"NumEnd\": 101,\n                  \"Literal\": \"4\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 103,\n                  \"LiteralEnd\": 108,\n                  \"Literal\": \"PATCH\"\n                },\n                \"Value\": {\n                  \"NumPos\": 110,\n                  \"NumEnd\": 111,\n                  \"Literal\": \"5\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 114,\n                  \"LiteralEnd\": 120,\n                  \"Literal\": \"DELETE\"\n                },\n                \"Value\": {\n                  \"NumPos\": 122,\n                  \"NumEnd\": 123,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 126,\n                  \"LiteralEnd\": 133,\n                  \"Literal\": \"CONNECT\"\n                },\n                \"Value\": {\n                  \"NumPos\": 135,\n                  \"NumEnd\": 136,\n                  \"Literal\": \"7\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 139,\n                  \"LiteralEnd\": 146,\n                  \"Literal\": \"OPTIONS\"\n                },\n                \"Value\": {\n                  \"NumPos\": 148,\n                  \"NumEnd\": 149,\n                  \"Literal\": \"8\",\n                  \"Base\": 10\n                }\n              },\n              {\n                \"Name\": {\n                  \"LiteralPos\": 152,\n                  \"LiteralEnd\": 157,\n                  \"Literal\": \"TRACE\"\n                },\n                \"Value\": {\n                  \"NumPos\": 159,\n                  \"NumEnd\": 160,\n                  \"Literal\": \"9\",\n                  \"Base\": 10\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 162,\n            \"RightParenPos\": 176,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 168,\n              \"NameEnd\": 172\n            },\n            \"Level\": {\n              \"NumPos\": 172,\n              \"NumEnd\": 174,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 183,\n          \"ColumnEnd\": 232,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"timestamp\",\n              \"QuoteType\": 3,\n              \"NamePos\": 183,\n              \"NameEnd\": 192\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 205,\n            \"RightParenPos\": 206,\n            \"Name\": {\n              \"Name\": \"DateTime64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 194,\n              \"NameEnd\": 204\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 205,\n                \"NumEnd\": 206,\n                \"Literal\": \"3\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 208,\n            \"RightParenPos\": 232,\n            \"Type\": {\n              \"Name\": \"DoubleDelta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 214,\n              \"NameEnd\": 225\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 227,\n              \"NameEnd\": 231\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 235,\n      \"EngineEnd\": 448,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 263,\n        \"RightParenPos\": 313,\n        \"Items\": {\n          \"ListPos\": 265,\n          \"ListEnd\": 312,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 265,\n                \"LiteralEnd\": 299,\n                \"Literal\": \"/clickhouse/tables/{layer}-{shard}\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 303,\n                \"LiteralEnd\": 312,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 315,\n        \"Expr\": {\n          \"ListPos\": 328,\n          \"ListEnd\": 344,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toDate\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 328,\n                  \"NameEnd\": 334\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 334,\n                  \"RightParenPos\": 344,\n                  \"Items\": {\n                    \"ListPos\": 335,\n                    \"ListEnd\": 344,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 335,\n                          \"NameEnd\": 344\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 374,\n        \"ListEnd\": 413,\n        \"Items\": [\n          {\n            \"TTLPos\": 374,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": {\n                  \"Name\": \"toDate\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 378,\n                  \"NameEnd\": 384\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 384,\n                  \"RightParenPos\": 394,\n                  \"Items\": {\n                    \"ListPos\": 385,\n                    \"ListEnd\": 394,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 385,\n                          \"NameEnd\": 394\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"Name\": {\n                  \"Name\": \"toIntervalDay\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 398,\n                  \"NameEnd\": 411\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 411,\n                  \"RightParenPos\": 413,\n                  \"Items\": {\n                    \"ListPos\": 412,\n                    \"ListEnd\": 413,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"NumPos\": 412,\n                          \"NumEnd\": 413,\n                          \"Literal\": \"3\",\n                          \"Base\": 10\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": {\n        \"SettingsPos\": 415,\n        \"ListEnd\": 448,\n        \"Items\": [\n          {\n            \"SettingsPos\": 424,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 424,\n              \"NameEnd\": 441\n            },\n            \"Expr\": {\n              \"NumPos\": 444,\n              \"NumEnd\": 448,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 346,\n        \"ListEnd\": 372,\n        \"Items\": [\n          {\n            \"OrderPos\": 346,\n            \"Expr\": {\n              \"LeftParenPos\": 355,\n              \"RightParenPos\": 372,\n              \"Items\": {\n                \"ListPos\": 356,\n                \"ListEnd\": 372,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"method\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 356,\n                      \"NameEnd\": 362\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"timestamp\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 363,\n                      \"NameEnd\": 372\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_index.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 1127,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 37\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 38,\n      \"SchemaEnd\": 690,\n      \"Columns\": [\n        {\n          \"NamePos\": 42,\n          \"ColumnEnd\": 74,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"common.id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 42,\n              \"NameEnd\": 51\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 53,\n              \"NameEnd\": 59\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 60,\n            \"RightParenPos\": 74,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 70\n            },\n            \"Level\": {\n              \"NumPos\": 70,\n              \"NumEnd\": 72,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 78,\n          \"ColumnEnd\": 110,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 78,\n              \"NameEnd\": 80\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 82,\n              \"NameEnd\": 88\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 89,\n            \"RightParenPos\": 110,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 95,\n              \"NameEnd\": 100\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 102,\n              \"NameEnd\": 106\n            },\n            \"Level\": {\n              \"NumPos\": 106,\n              \"NumEnd\": 108,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 114,\n          \"ColumnEnd\": 147,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx\",\n              \"QuoteType\": 3,\n              \"NamePos\": 114,\n              \"NameEnd\": 117\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 119,\n              \"NameEnd\": 125\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 126,\n            \"RightParenPos\": 147,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 132,\n              \"NameEnd\": 137\n            },\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 139,\n              \"NameEnd\": 143\n            },\n            \"Level\": {\n              \"NumPos\": 143,\n              \"NumEnd\": 145,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 151,\n          \"ColumnEnd\": 180,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"api_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 151,\n              \"NameEnd\": 157\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 159,\n              \"NameEnd\": 165\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 166,\n            \"RightParenPos\": 180,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 172,\n              \"NameEnd\": 176\n            },\n            \"Level\": {\n              \"NumPos\": 176,\n              \"NumEnd\": 178,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 184,\n          \"ColumnEnd\": 200,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"arr\",\n              \"QuoteType\": 3,\n              \"NamePos\": 184,\n              \"NameEnd\": 187\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 195,\n            \"RightParenPos\": 200,\n            \"Name\": {\n              \"Name\": \"Array\",\n              \"QuoteType\": 1,\n              \"NamePos\": 189,\n              \"NameEnd\": 194\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"Int64\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 195,\n                  \"NameEnd\": 200\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 205,\n          \"ColumnEnd\": 235,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"content\",\n              \"QuoteType\": 3,\n              \"NamePos\": 205,\n              \"NameEnd\": 212\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 214,\n              \"NameEnd\": 220\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 221,\n            \"RightParenPos\": 235,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 227,\n              \"NameEnd\": 231\n            },\n            \"Level\": {\n              \"NumPos\": 231,\n              \"NumEnd\": 233,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 239,\n          \"ColumnEnd\": 253,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"output\",\n              \"QuoteType\": 3,\n              \"NamePos\": 239,\n              \"NameEnd\": 245\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 247,\n              \"NameEnd\": 253\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"IndexPos\": 256,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id_common_id_bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 262,\n              \"NameEnd\": 287\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Fields\": [\n                {\n                  \"Name\": \"common\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 288,\n                  \"NameEnd\": 294\n                },\n                {\n                  \"Name\": \"id\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 295,\n                  \"NameEnd\": 297\n                }\n              ]\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 316,\n            \"RightParenPos\": 321,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 303,\n              \"NameEnd\": 315\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 316,\n                \"NumEnd\": 321,\n                \"Literal\": \"0.001\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 335,\n            \"NumEnd\": 336,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 339,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 345,\n              \"NameEnd\": 351\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 352,\n              \"NameEnd\": 354\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"Name\": {\n              \"Name\": \"minmax\",\n              \"QuoteType\": 1,\n              \"NamePos\": 360,\n              \"NameEnd\": 366\n            }\n          },\n          \"Granularity\": {\n            \"NumPos\": 379,\n            \"NumEnd\": 381,\n            \"Literal\": \"10\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 384,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 390,\n              \"NameEnd\": 396\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 397,\n              \"NameEnd\": 400\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 418,\n            \"RightParenPos\": 419,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 406,\n              \"NameEnd\": 418\n            },\n            \"Params\": null\n          },\n          \"Granularity\": {\n            \"NumPos\": 433,\n            \"NumEnd\": 434,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 437,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"api_id_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 443,\n              \"NameEnd\": 453\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"api_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 454,\n              \"NameEnd\": 460\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 470,\n            \"RightParenPos\": 473,\n            \"Name\": {\n              \"Name\": \"set\",\n              \"QuoteType\": 1,\n              \"NamePos\": 466,\n              \"NameEnd\": 469\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 470,\n                \"NumEnd\": 473,\n                \"Literal\": \"100\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 487,\n            \"NumEnd\": 488,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 491,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"arr_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 497,\n              \"NameEnd\": 504\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"arr\",\n              \"QuoteType\": 1,\n              \"NamePos\": 505,\n              \"NameEnd\": 508\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 527,\n            \"RightParenPos\": 531,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 514,\n              \"NameEnd\": 526\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 527,\n                \"NumEnd\": 531,\n                \"Literal\": \"0.01\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 545,\n            \"NumEnd\": 546,\n            \"Literal\": \"3\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 549,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"content_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 555,\n              \"NameEnd\": 566\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"content\",\n              \"QuoteType\": 1,\n              \"NamePos\": 567,\n              \"NameEnd\": 574\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 591,\n            \"RightParenPos\": 602,\n            \"Name\": {\n              \"Name\": \"tokenbf_v1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 580,\n              \"NameEnd\": 590\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 591,\n                \"NumEnd\": 596,\n                \"Literal\": \"30720\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 598,\n                \"NumEnd\": 599,\n                \"Literal\": \"2\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 601,\n                \"NumEnd\": 602,\n                \"Literal\": \"0\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 616,\n            \"NumEnd\": 617,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 620,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"output_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 626,\n              \"NameEnd\": 636\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"output\",\n              \"QuoteType\": 1,\n              \"NamePos\": 637,\n              \"NameEnd\": 643\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 660,\n            \"RightParenPos\": 674,\n            \"Name\": {\n              \"Name\": \"ngrambf_v1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 649,\n              \"NameEnd\": 659\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 660,\n                \"NumEnd\": 661,\n                \"Literal\": \"3\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 663,\n                \"NumEnd\": 668,\n                \"Literal\": \"10000\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 670,\n                \"NumEnd\": 671,\n                \"Literal\": \"2\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 673,\n                \"NumEnd\": 674,\n                \"Literal\": \"1\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 688,\n            \"NumEnd\": 689,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 692,\n      \"EngineEnd\": 1127,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 720,\n        \"RightParenPos\": 752,\n        \"Items\": {\n          \"ListPos\": 722,\n          \"ListEnd\": 751,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 722,\n                \"LiteralEnd\": 738,\n                \"Literal\": \"/root/test_local\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 742,\n                \"LiteralEnd\": 751,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 754,\n        \"Expr\": {\n          \"ListPos\": 767,\n          \"ListEnd\": 792,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toStartOfHour\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 767,\n                  \"NameEnd\": 780\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 780,\n                  \"RightParenPos\": 792,\n                  \"Items\": {\n                    \"ListPos\": 782,\n                    \"ListEnd\": 791,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 3,\n                          \"NamePos\": 782,\n                          \"NameEnd\": 791\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 850,\n        \"ListEnd\": 941,\n        \"Items\": [\n          {\n            \"TTLPos\": 850,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": {\n                  \"Name\": \"toStartOfHour\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 854,\n                  \"NameEnd\": 867\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 867,\n                  \"RightParenPos\": 879,\n                  \"Items\": {\n                    \"ListPos\": 869,\n                    \"ListEnd\": 878,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 3,\n                          \"NamePos\": 869,\n                          \"NameEnd\": 878\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 883,\n                \"Expr\": {\n                  \"NumPos\": 892,\n                  \"NumEnd\": 893,\n                  \"Literal\": \"7\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"DAY\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 894,\n                  \"NameEnd\": 897\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          },\n          {\n            \"TTLPos\": 850,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": {\n                  \"Name\": \"toStartOfHour\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 898,\n                  \"NameEnd\": 911\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 911,\n                  \"RightParenPos\": 923,\n                  \"Items\": {\n                    \"ListPos\": 913,\n                    \"ListEnd\": 922,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 3,\n                          \"NamePos\": 913,\n                          \"NameEnd\": 922\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 927,\n                \"Expr\": {\n                  \"NumPos\": 936,\n                  \"NumEnd\": 937,\n                  \"Literal\": \"2\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"DAY\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 938,\n                  \"NameEnd\": 941\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": {\n        \"SettingsPos\": 942,\n        \"ListEnd\": 1127,\n        \"Items\": [\n          {\n            \"SettingsPos\": 951,\n            \"Name\": {\n              \"Name\": \"execute_merges_on_single_replica_time_threshold\",\n              \"QuoteType\": 1,\n              \"NamePos\": 951,\n              \"NameEnd\": 998\n            },\n            \"Expr\": {\n              \"NumPos\": 999,\n              \"NumEnd\": 1003,\n              \"Literal\": \"1200\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 1005,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1005,\n              \"NameEnd\": 1022\n            },\n            \"Expr\": {\n              \"NumPos\": 1023,\n              \"NumEnd\": 1028,\n              \"Literal\": \"16384\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 1030,\n            \"Name\": {\n              \"Name\": \"max_bytes_to_merge_at_max_space_in_pool\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1030,\n              \"NameEnd\": 1069\n            },\n            \"Expr\": {\n              \"NumPos\": 1070,\n              \"NumEnd\": 1081,\n              \"Literal\": \"64424509440\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 1083,\n            \"Name\": {\n              \"Name\": \"storage_policy\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1083,\n              \"NameEnd\": 1097\n            },\n            \"Expr\": {\n              \"LiteralPos\": 1099,\n              \"LiteralEnd\": 1103,\n              \"Literal\": \"main\"\n            }\n          },\n          {\n            \"SettingsPos\": 1106,\n            \"Name\": {\n              \"Name\": \"ttl_only_drop_parts\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1106,\n              \"NameEnd\": 1125\n            },\n            \"Expr\": {\n              \"NumPos\": 1126,\n              \"NumEnd\": 1127,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 794,\n        \"ListEnd\": 848,\n        \"Items\": [\n          {\n            \"OrderPos\": 794,\n            \"Expr\": {\n              \"LeftParenPos\": 803,\n              \"RightParenPos\": 848,\n              \"Items\": {\n                \"ListPos\": 804,\n                \"ListEnd\": 847,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"toUnixTimestamp64Nano\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 804,\n                        \"NameEnd\": 825\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 825,\n                        \"RightParenPos\": 837,\n                        \"Items\": {\n                          \"ListPos\": 827,\n                          \"ListEnd\": 836,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"Name\": \"timestamp\",\n                                \"QuoteType\": 3,\n                                \"NamePos\": 827,\n                                \"NameEnd\": 836\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"api_id\",\n                      \"QuoteType\": 3,\n                      \"NamePos\": 841,\n                      \"NameEnd\": 847\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_keyword_partition_by.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 259,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 30\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": {\n      \"Value\": {\n        \"LiteralPos\": 37,\n        \"LiteralEnd\": 73,\n        \"Literal\": \"dad17568-b070-49d0-9ad1-7568b07029d0\"\n      }\n    },\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 75,\n      \"SchemaEnd\": 148,\n      \"Columns\": [\n        {\n          \"NamePos\": 82,\n          \"ColumnEnd\": 92,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"date\",\n              \"QuoteType\": 3,\n              \"NamePos\": 82,\n              \"NameEnd\": 86\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Date\",\n              \"QuoteType\": 1,\n              \"NamePos\": 88,\n              \"NameEnd\": 92\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 99,\n          \"ColumnEnd\": 109,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 3,\n              \"NamePos\": 99,\n              \"NameEnd\": 101\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 103,\n              \"NameEnd\": 109\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 116,\n          \"ColumnEnd\": 126,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 3,\n              \"NamePos\": 116,\n              \"NameEnd\": 118\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 120,\n              \"NameEnd\": 126\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 133,\n          \"ColumnEnd\": 143,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 3,\n              \"NamePos\": 133,\n              \"NameEnd\": 135\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 137,\n              \"NameEnd\": 143\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 150,\n      \"EngineEnd\": 259,\n      \"Name\": \"ReplacingMergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 182,\n        \"Expr\": {\n          \"ListPos\": 195,\n          \"ListEnd\": 199,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"date\",\n                \"QuoteType\": 1,\n                \"NamePos\": 195,\n                \"NameEnd\": 199\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": {\n        \"SettingsPos\": 226,\n        \"ListEnd\": 259,\n        \"Items\": [\n          {\n            \"SettingsPos\": 235,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 235,\n              \"NameEnd\": 252\n            },\n            \"Expr\": {\n              \"NumPos\": 255,\n              \"NumEnd\": 259,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 204,\n        \"ListEnd\": 220,\n        \"Items\": [\n          {\n            \"OrderPos\": 204,\n            \"Expr\": {\n              \"LeftParenPos\": 213,\n              \"RightParenPos\": 220,\n              \"Items\": {\n                \"ListPos\": 214,\n                \"ListEnd\": 220,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 214,\n                      \"NameEnd\": 216\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 218,\n                      \"NameEnd\": 220\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_null_engine.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 172,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"logs\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \"t0\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 20\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 21,\n      \"Expr\": {\n        \"Name\": \"default\",\n        \"QuoteType\": 1,\n        \"NamePos\": 32,\n        \"NameEnd\": 39\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 40,\n      \"SchemaEnd\": 157,\n      \"Columns\": [\n        {\n          \"NamePos\": 47,\n          \"ColumnEnd\": 78,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"trace_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 47,\n              \"NameEnd\": 55\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 57,\n              \"NameEnd\": 63\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 64,\n            \"RightParenPos\": 78,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 70,\n              \"NameEnd\": 74\n            },\n            \"Level\": {\n              \"NumPos\": 74,\n              \"NumEnd\": 76,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"IndexPos\": 84,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"trace_id_bloom_idx\",\n              \"QuoteType\": 1,\n              \"NamePos\": 90,\n              \"NameEnd\": 108\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"trace_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 109,\n              \"NameEnd\": 117\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 136,\n            \"RightParenPos\": 140,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 123,\n              \"NameEnd\": 135\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 136,\n                \"NumEnd\": 140,\n                \"Literal\": \"0.01\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 154,\n            \"NumEnd\": 156,\n            \"Literal\": \"64\",\n            \"Base\": 10\n          }\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 159,\n      \"EngineEnd\": 172,\n      \"Name\": \"Null\",\n      \"Params\": {\n        \"LeftParenPos\": 172,\n        \"RightParenPos\": 173,\n        \"Items\": {\n          \"ListPos\": 173,\n          \"ListEnd\": 173,\n          \"HasDistinct\": false,\n          \"Items\": []\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": null\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_nullable.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 420,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \".inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5\",\n        \"QuoteType\": 3,\n        \"NamePos\": 19,\n        \"NameEnd\": 62\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": {\n      \"Value\": {\n        \"LiteralPos\": 74,\n        \"LiteralEnd\": 110,\n        \"Literal\": \"27673372-7973-44f5-a767-33727973c4f5\"\n      }\n    },\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 112,\n      \"SchemaEnd\": 313,\n      \"Columns\": [\n        {\n          \"NamePos\": 119,\n          \"ColumnEnd\": 129,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 3,\n              \"NamePos\": 119,\n              \"NameEnd\": 121\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 123,\n              \"NameEnd\": 129\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 136,\n          \"ColumnEnd\": 146,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 3,\n              \"NamePos\": 136,\n              \"NameEnd\": 138\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 140,\n              \"NameEnd\": 146\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 153,\n          \"ColumnEnd\": 178,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 3,\n              \"NamePos\": 153,\n              \"NameEnd\": 155\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 172,\n            \"RightParenPos\": 178,\n            \"Name\": {\n              \"Name\": \"LowCardinality\",\n              \"QuoteType\": 1,\n              \"NamePos\": 157,\n              \"NameEnd\": 171\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 172,\n                  \"NameEnd\": 178\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 186,\n          \"ColumnEnd\": 211,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 3,\n              \"NamePos\": 186,\n              \"NameEnd\": 188\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 205,\n            \"RightParenPos\": 211,\n            \"Name\": {\n              \"Name\": \"LowCardinality\",\n              \"QuoteType\": 1,\n              \"NamePos\": 190,\n              \"NameEnd\": 204\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 205,\n                  \"NameEnd\": 211\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 219,\n          \"ColumnEnd\": 235,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 3,\n              \"NamePos\": 219,\n              \"NameEnd\": 221\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 234,\n            \"RightParenPos\": 235,\n            \"Name\": {\n              \"Name\": \"DateTime64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 223,\n              \"NameEnd\": 233\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 234,\n                \"NumEnd\": 235,\n                \"Literal\": \"3\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 243,\n          \"ColumnEnd\": 269,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 3,\n              \"NamePos\": 243,\n              \"NameEnd\": 245\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 256,\n            \"RightParenPos\": 269,\n            \"Name\": {\n              \"Name\": \"Nullable\",\n              \"QuoteType\": 1,\n              \"NamePos\": 247,\n              \"NameEnd\": 255\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 267,\n                \"RightParenPos\": 268,\n                \"Name\": {\n                  \"Name\": \"DateTime64\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 256,\n                  \"NameEnd\": 266\n                },\n                \"Params\": [\n                  {\n                    \"NumPos\": 267,\n                    \"NumEnd\": 268,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  }\n                ]\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 277,\n          \"ColumnEnd\": 311,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"succeed_at\",\n              \"QuoteType\": 3,\n              \"NamePos\": 277,\n              \"NameEnd\": 287\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 298,\n            \"RightParenPos\": 311,\n            \"Name\": {\n              \"Name\": \"Nullable\",\n              \"QuoteType\": 1,\n              \"NamePos\": 289,\n              \"NameEnd\": 297\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 309,\n                \"RightParenPos\": 310,\n                \"Name\": {\n                  \"Name\": \"DateTime64\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 298,\n                  \"NameEnd\": 308\n                },\n                \"Params\": [\n                  {\n                    \"NumPos\": 309,\n                    \"NumEnd\": 310,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  }\n                ]\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 315,\n      \"EngineEnd\": 420,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 334,\n        \"Expr\": {\n          \"ListPos\": 347,\n          \"ListEnd\": 368,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LeftExpr\": {\n                  \"Name\": {\n                    \"Name\": \"xxHash32\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 347,\n                    \"NameEnd\": 355\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 355,\n                    \"RightParenPos\": 362,\n                    \"Items\": {\n                      \"ListPos\": 356,\n                      \"ListEnd\": 362,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Name\": \"tag_id\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 356,\n                            \"NameEnd\": 362\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Operation\": \"%\",\n                \"RightExpr\": {\n                  \"NumPos\": 366,\n                  \"NumEnd\": 368,\n                  \"Literal\": \"20\",\n                  \"Base\": 10\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": {\n        \"SettingsPos\": 387,\n        \"ListEnd\": 420,\n        \"Items\": [\n          {\n            \"SettingsPos\": 396,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 396,\n              \"NameEnd\": 413\n            },\n            \"Expr\": {\n              \"NumPos\": 416,\n              \"NumEnd\": 420,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 369,\n        \"ListEnd\": 386,\n        \"Items\": [\n          {\n            \"OrderPos\": 369,\n            \"Expr\": {\n              \"Name\": \"label_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 378,\n              \"NameEnd\": 386\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_on_clsuter.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 399,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 31\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 32,\n        \"NameEnd\": 44\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 45,\n      \"Expr\": {\n        \"LiteralPos\": 57,\n        \"LiteralEnd\": 72,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 74,\n      \"SchemaEnd\": 227,\n      \"Columns\": [\n        {\n          \"NamePos\": 80,\n          \"ColumnEnd\": 89,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 80,\n              \"NameEnd\": 82\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 83,\n              \"NameEnd\": 89\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 95,\n          \"ColumnEnd\": 104,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 95,\n              \"NameEnd\": 97\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 98,\n              \"NameEnd\": 104\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 110,\n          \"ColumnEnd\": 119,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 110,\n              \"NameEnd\": 112\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 113,\n              \"NameEnd\": 119\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 125,\n          \"ColumnEnd\": 136,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 125,\n              \"NameEnd\": 127\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 128,\n              \"NameEnd\": 136\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 142,\n          \"ColumnEnd\": 153,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 142,\n              \"NameEnd\": 144\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 145,\n              \"NameEnd\": 153\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 159,\n          \"ColumnEnd\": 179,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 159,\n              \"NameEnd\": 161\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 166,\n            \"RightParenPos\": 179,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 162,\n              \"NameEnd\": 165\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 166,\n                  \"NameEnd\": 172\n                }\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 173,\n                  \"NameEnd\": 179\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 186,\n          \"ColumnEnd\": 195,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 1,\n              \"NamePos\": 186,\n              \"NameEnd\": 188\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 189,\n              \"NameEnd\": 195\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 201,\n          \"ColumnEnd\": 225,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f7\",\n              \"QuoteType\": 1,\n              \"NamePos\": 201,\n              \"NameEnd\": 203\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 204,\n              \"NameEnd\": 212\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"Name\": {\n              \"Name\": \"now\",\n              \"QuoteType\": 1,\n              \"NamePos\": 221,\n              \"NameEnd\": 224\n            },\n            \"Params\": {\n              \"LeftParenPos\": 224,\n              \"RightParenPos\": 225,\n              \"Items\": {\n                \"ListPos\": 225,\n                \"ListEnd\": 225,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 229,\n      \"EngineEnd\": 399,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 257,\n        \"RightParenPos\": 325,\n        \"Items\": {\n          \"ListPos\": 259,\n          \"ListEnd\": 324,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 259,\n                \"LiteralEnd\": 311,\n                \"Literal\": \"/clickhouse/tables/{layer}-{shard}/test/events_local\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 315,\n                \"LiteralEnd\": 324,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 353,\n        \"Expr\": {\n          \"ListPos\": 366,\n          \"ListEnd\": 379,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMMDD\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 366,\n                  \"NameEnd\": 376\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 376,\n                  \"RightParenPos\": 379,\n                  \"Items\": {\n                    \"ListPos\": 377,\n                    \"ListEnd\": 379,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f3\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 377,\n                          \"NameEnd\": 379\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 327,\n        \"ListEnd\": 352,\n        \"Items\": [\n          {\n            \"TTLPos\": 327,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"f3\",\n                \"QuoteType\": 1,\n                \"NamePos\": 331,\n                \"NameEnd\": 333\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 336,\n                \"Expr\": {\n                  \"NumPos\": 345,\n                  \"NumEnd\": 346,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 347,\n                  \"NameEnd\": 352\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 381,\n        \"ListEnd\": 399,\n        \"Items\": [\n          {\n            \"OrderPos\": 381,\n            \"Expr\": {\n              \"LeftParenPos\": 390,\n              \"RightParenPos\": 399,\n              \"Items\": {\n                \"ListPos\": 391,\n                \"ListEnd\": 399,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 391,\n                      \"NameEnd\": 393\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 394,\n                      \"NameEnd\": 396\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 397,\n                      \"NameEnd\": 399\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_projection.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 270,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 19\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 20,\n      \"SchemaEnd\": 229,\n      \"Columns\": [\n        {\n          \"NamePos\": 27,\n          \"ColumnEnd\": 47,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"event_time\",\n              \"QuoteType\": 3,\n              \"NamePos\": 27,\n              \"NameEnd\": 37\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 47\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 54,\n          \"ColumnEnd\": 70,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"event_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 54,\n              \"NameEnd\": 62\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 64,\n              \"NameEnd\": 70\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 77,\n          \"ColumnEnd\": 92,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"user_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 77,\n              \"NameEnd\": 84\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 86,\n              \"NameEnd\": 92\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 99,\n          \"ColumnEnd\": 118,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"huge_string\",\n              \"QuoteType\": 3,\n              \"NamePos\": 99,\n              \"NameEnd\": 110\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 112,\n              \"NameEnd\": 118\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"IncludeProjectionKeyword\": true,\n          \"ProjectionPos\": 124,\n          \"Identifier\": {\n            \"Ident\": {\n              \"Name\": \"order_by_user_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 135,\n              \"NameEnd\": 151\n            },\n            \"DotIdent\": null\n          },\n          \"Select\": {\n            \"LeftParenPos\": 156,\n            \"RightParenPos\": 227,\n            \"With\": null,\n            \"SelectColumns\": {\n              \"ListPos\": 185,\n              \"ListEnd\": 197,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"_part_offset\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 185,\n                    \"NameEnd\": 197\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"GroupBy\": null,\n            \"OrderBy\": {\n              \"OrderByPos\": 206,\n              \"Columns\": {\n                \"ListPos\": 215,\n                \"ListEnd\": 222,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"user_id\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 215,\n                      \"NameEnd\": 222\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            }\n          }\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 231,\n      \"EngineEnd\": 270,\n      \"Name\": \"MergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 249,\n        \"RightParenPos\": 250,\n        \"Items\": {\n          \"ListPos\": 250,\n          \"ListEnd\": 250,\n          \"HasDistinct\": false,\n          \"Items\": []\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 252,\n        \"ListEnd\": 270,\n        \"Items\": [\n          {\n            \"OrderPos\": 252,\n            \"Expr\": {\n              \"LeftParenPos\": 261,\n              \"RightParenPos\": 270,\n              \"Items\": {\n                \"ListPos\": 262,\n                \"ListEnd\": 270,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"event_id\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 262,\n                      \"NameEnd\": 270\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_projection_group_by_only.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 411,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"events\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 19\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 20,\n      \"SchemaEnd\": 356,\n      \"Columns\": [\n        {\n          \"NamePos\": 27,\n          \"ColumnEnd\": 47,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"event_time\",\n              \"QuoteType\": 3,\n              \"NamePos\": 27,\n              \"NameEnd\": 37\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 47\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 54,\n          \"ColumnEnd\": 72,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"event_type\",\n              \"QuoteType\": 3,\n              \"NamePos\": 54,\n              \"NameEnd\": 64\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 72\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 79,\n          \"ColumnEnd\": 94,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"user_id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 79,\n              \"NameEnd\": 86\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 88,\n              \"NameEnd\": 94\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 101,\n          \"ColumnEnd\": 115,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"value\",\n              \"QuoteType\": 3,\n              \"NamePos\": 101,\n              \"NameEnd\": 106\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Float64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 108,\n              \"NameEnd\": 115\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"IncludeProjectionKeyword\": true,\n          \"ProjectionPos\": 121,\n          \"Identifier\": {\n            \"Ident\": {\n              \"Name\": \"hourly_aggregates\",\n              \"QuoteType\": 1,\n              \"NamePos\": 132,\n              \"NameEnd\": 149\n            },\n            \"DotIdent\": null\n          },\n          \"Select\": {\n            \"LeftParenPos\": 154,\n            \"RightParenPos\": 354,\n            \"With\": null,\n            \"SelectColumns\": {\n              \"ListPos\": 183,\n              \"ListEnd\": 315,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toStartOfHour\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 183,\n                      \"NameEnd\": 196\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 196,\n                      \"RightParenPos\": 207,\n                      \"Items\": {\n                        \"ListPos\": 197,\n                        \"ListEnd\": 207,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": \"event_time\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 197,\n                              \"NameEnd\": 207\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"hour\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 212,\n                    \"NameEnd\": 216\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"event_type\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 230,\n                    \"NameEnd\": 240\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"count\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 254,\n                      \"NameEnd\": 259\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 259,\n                      \"RightParenPos\": 260,\n                      \"Items\": {\n                        \"ListPos\": 260,\n                        \"ListEnd\": 260,\n                        \"HasDistinct\": false,\n                        \"Items\": []\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"event_count\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 265,\n                    \"NameEnd\": 276\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"sum\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 290,\n                      \"NameEnd\": 293\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 293,\n                      \"RightParenPos\": 299,\n                      \"Items\": {\n                        \"ListPos\": 294,\n                        \"ListEnd\": 299,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": \"value\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 294,\n                              \"NameEnd\": 299\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"total_value\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 304,\n                    \"NameEnd\": 315\n                  }\n                }\n              ]\n            },\n            \"GroupBy\": {\n              \"GroupByPos\": 324,\n              \"GroupByEnd\": 354,\n              \"AggregateType\": \"\",\n              \"Expr\": {\n                \"ListPos\": 333,\n                \"ListEnd\": 349,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"hour\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 333,\n                      \"NameEnd\": 337\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"event_type\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 339,\n                      \"NameEnd\": 349\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"WithCube\": false,\n              \"WithRollup\": false,\n              \"WithTotals\": false\n            },\n            \"OrderBy\": null\n          }\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 358,\n      \"EngineEnd\": 411,\n      \"Name\": \"MergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 376,\n        \"RightParenPos\": 377,\n        \"Items\": {\n          \"ListPos\": 377,\n          \"ListEnd\": 377,\n          \"HasDistinct\": false,\n          \"Items\": []\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 379,\n        \"ListEnd\": 411,\n        \"Items\": [\n          {\n            \"OrderPos\": 379,\n            \"Expr\": {\n              \"LeftParenPos\": 388,\n              \"RightParenPos\": 411,\n              \"Items\": {\n                \"ListPos\": 389,\n                \"ListEnd\": 411,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"event_time\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 389,\n                      \"NameEnd\": 399\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"event_type\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 401,\n                      \"NameEnd\": 411\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_qbit.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 90,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \"qbit_example\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 30\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 31,\n      \"SchemaEnd\": 73,\n      \"Columns\": [\n        {\n          \"NamePos\": 37,\n          \"ColumnEnd\": 46,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 37,\n              \"NameEnd\": 39\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 40,\n              \"NameEnd\": 46\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 52,\n          \"ColumnEnd\": 71,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"vec\",\n              \"QuoteType\": 1,\n              \"NamePos\": 52,\n              \"NameEnd\": 55\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 61,\n            \"RightParenPos\": 71,\n            \"Name\": {\n              \"Name\": \"QBit\",\n              \"QuoteType\": 1,\n              \"NamePos\": 56,\n              \"NameEnd\": 60\n            },\n            \"Params\": [\n              {\n                \"Name\": \"Float32\",\n                \"QuoteType\": 1,\n                \"NamePos\": 61,\n                \"NameEnd\": 68\n              },\n              {\n                \"NumPos\": 70,\n                \"NumEnd\": 71,\n                \"Literal\": \"8\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 75,\n      \"EngineEnd\": 90,\n      \"Name\": \"Memory\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": null\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_sample_by.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 351,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"default\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 20\n      },\n      \"Table\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 21,\n        \"NameEnd\": 25\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": {\n      \"Value\": {\n        \"LiteralPos\": 32,\n        \"LiteralEnd\": 68,\n        \"Literal\": \"87887901-e33c-497e-8788-7901e33c997e\"\n      }\n    },\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 70,\n      \"SchemaEnd\": 124,\n      \"Columns\": [\n        {\n          \"NamePos\": 77,\n          \"ColumnEnd\": 89,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 3,\n              \"NamePos\": 77,\n              \"NameEnd\": 79\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 81,\n              \"NameEnd\": 89\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 96,\n          \"ColumnEnd\": 106,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 3,\n              \"NamePos\": 96,\n              \"NameEnd\": 98\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 100,\n              \"NameEnd\": 106\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 113,\n          \"ColumnEnd\": 123,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 3,\n              \"NamePos\": 113,\n              \"NameEnd\": 115\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 117,\n              \"NameEnd\": 123\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 126,\n      \"EngineEnd\": 351,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 154,\n        \"RightParenPos\": 217,\n        \"Items\": {\n          \"ListPos\": 156,\n          \"ListEnd\": 216,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 156,\n                \"LiteralEnd\": 203,\n                \"Literal\": \"/clickhouse/tables/{layer}/{shard}/default/test\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 207,\n                \"LiteralEnd\": 216,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 219,\n        \"Expr\": {\n          \"ListPos\": 232,\n          \"ListEnd\": 250,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMM\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 232,\n                  \"NameEnd\": 240\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 240,\n                  \"RightParenPos\": 250,\n                  \"Items\": {\n                    \"ListPos\": 241,\n                    \"ListEnd\": 250,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 241,\n                          \"NameEnd\": 250\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": {\n        \"SamplePos\": 301,\n        \"Expr\": {\n          \"Name\": \"userid\",\n          \"QuoteType\": 1,\n          \"NamePos\": 311,\n          \"NameEnd\": 317\n        }\n      },\n      \"TTL\": null,\n      \"Settings\": {\n        \"SettingsPos\": 318,\n        \"ListEnd\": 351,\n        \"Items\": [\n          {\n            \"SettingsPos\": 327,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 327,\n              \"NameEnd\": 344\n            },\n            \"Expr\": {\n              \"NumPos\": 347,\n              \"NumEnd\": 351,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 252,\n        \"ListEnd\": 299,\n        \"Items\": [\n          {\n            \"OrderPos\": 252,\n            \"Expr\": {\n              \"LeftParenPos\": 261,\n              \"RightParenPos\": 299,\n              \"Items\": {\n                \"ListPos\": 262,\n                \"ListEnd\": 299,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"contractid\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 262,\n                      \"NameEnd\": 272\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"toDate\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 274,\n                        \"NameEnd\": 280\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 280,\n                        \"RightParenPos\": 290,\n                        \"Items\": {\n                          \"ListPos\": 281,\n                          \"ListEnd\": 290,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"Name\": \"timestamp\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 281,\n                                \"NameEnd\": 290\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"userid\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 293,\n                      \"NameEnd\": 299\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_ttl_policy.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 203,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"tab\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 16\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 17,\n      \"SchemaEnd\": 45,\n      \"Columns\": [\n        {\n          \"NamePos\": 23,\n          \"ColumnEnd\": 33,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 23,\n              \"NameEnd\": 24\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 25,\n              \"NameEnd\": 33\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 39,\n          \"ColumnEnd\": 44,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"a\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 40\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Int\",\n              \"QuoteType\": 1,\n              \"NamePos\": 41,\n              \"NameEnd\": 44\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 51,\n      \"EngineEnd\": 203,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 70,\n        \"Expr\": {\n          \"ListPos\": 83,\n          \"ListEnd\": 93,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMM\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 83,\n                  \"NameEnd\": 91\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 91,\n                  \"RightParenPos\": 93,\n                  \"Items\": {\n                    \"ListPos\": 92,\n                    \"ListEnd\": 93,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"d\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 92,\n                          \"NameEnd\": 93\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 106,\n        \"ListEnd\": 203,\n        \"Items\": [\n          {\n            \"TTLPos\": 106,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"d\",\n                \"QuoteType\": 1,\n                \"NamePos\": 110,\n                \"NameEnd\": 111\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 114,\n                \"Expr\": {\n                  \"NumPos\": 123,\n                  \"NumEnd\": 124,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 125,\n                  \"NameEnd\": 130\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": {\n              \"Item\": {\n                \"RulePos\": 131,\n                \"ToVolume\": null,\n                \"ToDisk\": null,\n                \"Action\": {\n                  \"ActionPos\": 131,\n                  \"ActionEnd\": 137,\n                  \"Action\": \"DELETE\",\n                  \"Codec\": null\n                }\n              },\n              \"Where\": null,\n              \"GroupBy\": null\n            }\n          },\n          {\n            \"TTLPos\": 106,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"d\",\n                \"QuoteType\": 1,\n                \"NamePos\": 143,\n                \"NameEnd\": 144\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 147,\n                \"Expr\": {\n                  \"NumPos\": 156,\n                  \"NumEnd\": 157,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"WEEK\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 158,\n                  \"NameEnd\": 162\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": {\n              \"Item\": {\n                \"RulePos\": 163,\n                \"ToVolume\": {\n                  \"LiteralPos\": 174,\n                  \"LiteralEnd\": 177,\n                  \"Literal\": \"aaa\"\n                },\n                \"ToDisk\": null,\n                \"Action\": null\n              },\n              \"Where\": null,\n              \"GroupBy\": null\n            }\n          },\n          {\n            \"TTLPos\": 106,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"d\",\n                \"QuoteType\": 1,\n                \"NamePos\": 184,\n                \"NameEnd\": 185\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 188,\n                \"Expr\": {\n                  \"NumPos\": 197,\n                  \"NumEnd\": 198,\n                  \"Literal\": \"2\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"WEEK\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 199,\n                  \"NameEnd\": 203\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": {\n              \"Item\": {\n                \"RulePos\": 204,\n                \"ToVolume\": null,\n                \"ToDisk\": {\n                  \"LiteralPos\": 213,\n                  \"LiteralEnd\": 216,\n                  \"Literal\": \"bbb\"\n                },\n                \"Action\": null\n              },\n              \"Where\": null,\n              \"GroupBy\": null\n            }\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 95,\n        \"ListEnd\": 105,\n        \"Items\": [\n          {\n            \"OrderPos\": 95,\n            \"Expr\": {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 104,\n              \"NameEnd\": 105\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  },\n  {\n    \"CreatePos\": 221,\n    \"StatementEnd\": 364,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table_with_where\",\n        \"QuoteType\": 1,\n        \"NamePos\": 234,\n        \"NameEnd\": 250\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 251,\n      \"SchemaEnd\": 279,\n      \"Columns\": [\n        {\n          \"NamePos\": 257,\n          \"ColumnEnd\": 267,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 257,\n              \"NameEnd\": 258\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 259,\n              \"NameEnd\": 267\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 273,\n          \"ColumnEnd\": 278,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"a\",\n              \"QuoteType\": 1,\n              \"NamePos\": 273,\n              \"NameEnd\": 274\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Int\",\n              \"QuoteType\": 1,\n              \"NamePos\": 275,\n              \"NameEnd\": 278\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 285,\n      \"EngineEnd\": 364,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 304,\n        \"Expr\": {\n          \"ListPos\": 317,\n          \"ListEnd\": 327,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMM\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 317,\n                  \"NameEnd\": 325\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 325,\n                  \"RightParenPos\": 327,\n                  \"Items\": {\n                    \"ListPos\": 326,\n                    \"ListEnd\": 327,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"d\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 326,\n                          \"NameEnd\": 327\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 340,\n        \"ListEnd\": 364,\n        \"Items\": [\n          {\n            \"TTLPos\": 340,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"d\",\n                \"QuoteType\": 1,\n                \"NamePos\": 344,\n                \"NameEnd\": 345\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 348,\n                \"Expr\": {\n                  \"NumPos\": 357,\n                  \"NumEnd\": 358,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 359,\n                  \"NameEnd\": 364\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": {\n              \"Item\": {\n                \"RulePos\": 365,\n                \"ToVolume\": null,\n                \"ToDisk\": null,\n                \"Action\": {\n                  \"ActionPos\": 365,\n                  \"ActionEnd\": 371,\n                  \"Action\": \"DELETE\",\n                  \"Codec\": null\n                }\n              },\n              \"Where\": {\n                \"WherePos\": 372,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"Name\": {\n                      \"Name\": \"toDayOfWeek\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 378,\n                      \"NameEnd\": 389\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 389,\n                      \"RightParenPos\": 391,\n                      \"Items\": {\n                        \"ListPos\": 390,\n                        \"ListEnd\": 391,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": \"d\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 390,\n                              \"NameEnd\": 391\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Operation\": \"=\",\n                  \"RightExpr\": {\n                    \"NumPos\": 395,\n                    \"NumEnd\": 396,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                }\n              },\n              \"GroupBy\": null\n            }\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 329,\n        \"ListEnd\": 339,\n        \"Items\": [\n          {\n            \"OrderPos\": 329,\n            \"Expr\": {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 338,\n              \"NameEnd\": 339\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  },\n  {\n    \"CreatePos\": 399,\n    \"StatementEnd\": 763,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table_for_recompression\",\n        \"QuoteType\": 1,\n        \"NamePos\": 412,\n        \"NameEnd\": 435\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 436,\n      \"SchemaEnd\": 487,\n      \"Columns\": [\n        {\n          \"NamePos\": 442,\n          \"ColumnEnd\": 452,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 442,\n              \"NameEnd\": 443\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 444,\n              \"NameEnd\": 452\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 458,\n          \"ColumnEnd\": 468,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"key\",\n              \"QuoteType\": 1,\n              \"NamePos\": 458,\n              \"NameEnd\": 461\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 462,\n              \"NameEnd\": 468\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 474,\n          \"ColumnEnd\": 486,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 474,\n              \"NameEnd\": 479\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 480,\n              \"NameEnd\": 486\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 489,\n      \"EngineEnd\": 763,\n      \"Name\": \"MergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 505,\n        \"RightParenPos\": 506,\n        \"Items\": {\n          \"ListPos\": 506,\n          \"ListEnd\": 506,\n          \"HasDistinct\": false,\n          \"Items\": []\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 525,\n        \"Expr\": {\n          \"ListPos\": 538,\n          \"ListEnd\": 541,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"key\",\n                \"QuoteType\": 1,\n                \"NamePos\": 538,\n                \"NameEnd\": 541\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 542,\n        \"ListEnd\": 614,\n        \"Items\": [\n          {\n            \"TTLPos\": 542,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"d\",\n                \"QuoteType\": 1,\n                \"NamePos\": 546,\n                \"NameEnd\": 547\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 550,\n                \"Expr\": {\n                  \"NumPos\": 559,\n                  \"NumEnd\": 560,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 561,\n                  \"NameEnd\": 566\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": {\n              \"Item\": {\n                \"RulePos\": 567,\n                \"ToVolume\": null,\n                \"ToDisk\": null,\n                \"Action\": {\n                  \"ActionPos\": 567,\n                  \"ActionEnd\": 577,\n                  \"Action\": \"RECOMPRESS\",\n                  \"Codec\": {\n                    \"CodecPos\": 578,\n                    \"RightParenPos\": 593,\n                    \"Type\": null,\n                    \"TypeLevel\": null,\n                    \"Name\": {\n                      \"Name\": \"ZSTD\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 584,\n                      \"NameEnd\": 588\n                    },\n                    \"Level\": {\n                      \"NumPos\": 588,\n                      \"NumEnd\": 591,\n                      \"Literal\": \"17\",\n                      \"Base\": 10\n                    }\n                  }\n                }\n              },\n              \"Where\": null,\n              \"GroupBy\": null\n            }\n          },\n          {\n            \"TTLPos\": 542,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"d\",\n                \"QuoteType\": 1,\n                \"NamePos\": 595,\n                \"NameEnd\": 596\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 599,\n                \"Expr\": {\n                  \"NumPos\": 608,\n                  \"NumEnd\": 609,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"YEAR\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 610,\n                  \"NameEnd\": 614\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": {\n              \"Item\": {\n                \"RulePos\": 615,\n                \"ToVolume\": null,\n                \"ToDisk\": null,\n                \"Action\": {\n                  \"ActionPos\": 615,\n                  \"ActionEnd\": 625,\n                  \"Action\": \"RECOMPRESS\",\n                  \"Codec\": {\n                    \"CodecPos\": 626,\n                    \"RightParenPos\": 642,\n                    \"Type\": null,\n                    \"TypeLevel\": null,\n                    \"Name\": {\n                      \"Name\": \"LZ4HC\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 632,\n                      \"NameEnd\": 637\n                    },\n                    \"Level\": {\n                      \"NumPos\": 637,\n                      \"NumEnd\": 640,\n                      \"Literal\": \"10\",\n                      \"Base\": 10\n                    }\n                  }\n                }\n              },\n              \"Where\": null,\n              \"GroupBy\": null\n            }\n          }\n        ]\n      },\n      \"Settings\": {\n        \"SettingsPos\": 643,\n        \"ListEnd\": 763,\n        \"Items\": [\n          {\n            \"SettingsPos\": 652,\n            \"Name\": {\n              \"Name\": \"min_rows_for_wide_part\",\n              \"QuoteType\": 1,\n              \"NamePos\": 652,\n              \"NameEnd\": 674\n            },\n            \"Expr\": {\n              \"NumPos\": 677,\n              \"NumEnd\": 678,\n              \"Literal\": \"0\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 680,\n            \"Name\": {\n              \"Name\": \"min_bytes_for_wide_part\",\n              \"QuoteType\": 1,\n              \"NamePos\": 680,\n              \"NameEnd\": 703\n            },\n            \"Expr\": {\n              \"NumPos\": 706,\n              \"NumEnd\": 707,\n              \"Literal\": \"0\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 709,\n            \"Name\": {\n              \"Name\": \"allow_experimental_replacing_merge_with_cleanup\",\n              \"QuoteType\": 1,\n              \"NamePos\": 709,\n              \"NameEnd\": 756\n            },\n            \"Expr\": {\n              \"LiteralPos\": 759,\n              \"LiteralEnd\": 763,\n              \"Literal\": \"true\"\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 508,\n        \"ListEnd\": 523,\n        \"Items\": [\n          {\n            \"OrderPos\": 508,\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"tuple\",\n                \"QuoteType\": 1,\n                \"NamePos\": 517,\n                \"NameEnd\": 522\n              },\n              \"Params\": {\n                \"LeftParenPos\": 522,\n                \"RightParenPos\": 523,\n                \"Items\": {\n                  \"ListPos\": 523,\n                  \"ListEnd\": 523,\n                  \"HasDistinct\": false,\n                  \"Items\": []\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_tuple_fields.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 347,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t0\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 15\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 16,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 42\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 43,\n      \"SchemaEnd\": 204,\n      \"Columns\": [\n        {\n          \"NamePos\": 50,\n          \"ColumnEnd\": 62,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"tup0\",\n              \"QuoteType\": 3,\n              \"NamePos\": 50,\n              \"NameEnd\": 54\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 61,\n            \"RightParenPos\": 62,\n            \"Name\": {\n              \"Name\": \"Tuple\",\n              \"QuoteType\": 1,\n              \"NamePos\": 56,\n              \"NameEnd\": 61\n            },\n            \"Params\": null\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 70,\n          \"ColumnEnd\": 95,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"tup1\",\n              \"QuoteType\": 3,\n              \"NamePos\": 70,\n              \"NameEnd\": 74\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 82,\n            \"RightParenPos\": 95,\n            \"Name\": {\n              \"Name\": \"Tuple\",\n              \"QuoteType\": 1,\n              \"NamePos\": 76,\n              \"NameEnd\": 81\n            },\n            \"Columns\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 82,\n                  \"NameEnd\": 88\n                }\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"Int64\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 90,\n                  \"NameEnd\": 95\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 103,\n          \"ColumnEnd\": 144,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"tup2\",\n              \"QuoteType\": 3,\n              \"NamePos\": 103,\n              \"NameEnd\": 107\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 115,\n            \"RightParenPos\": 144,\n            \"Name\": {\n              \"Name\": \"Tuple\",\n              \"QuoteType\": 1,\n              \"NamePos\": 109,\n              \"NameEnd\": 114\n            },\n            \"Columns\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 115,\n                  \"NameEnd\": 121\n                }\n              },\n              {\n                \"LeftParenPos\": 129,\n                \"RightParenPos\": 143,\n                \"Name\": {\n                  \"Name\": \"Tuple\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 123,\n                  \"NameEnd\": 128\n                },\n                \"Columns\": [\n                  {\n                    \"Name\": {\n                      \"Name\": \"String\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 129,\n                      \"NameEnd\": 135\n                    }\n                  },\n                  {\n                    \"Name\": {\n                      \"Name\": \"String\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 137,\n                      \"NameEnd\": 143\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 152,\n          \"ColumnEnd\": 202,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"tup3\",\n              \"QuoteType\": 3,\n              \"NamePos\": 152,\n              \"NameEnd\": 156\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 164,\n            \"RightParenPos\": 202,\n            \"Name\": {\n              \"Name\": \"Tuple\",\n              \"QuoteType\": 1,\n              \"NamePos\": 158,\n              \"NameEnd\": 163\n            },\n            \"Columns\": [\n              {\n                \"NamePos\": 164,\n                \"ColumnEnd\": 172,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"a\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 164,\n                    \"NameEnd\": 165\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"Name\": {\n                    \"Name\": \"String\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 166,\n                    \"NameEnd\": 172\n                  }\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              },\n              {\n                \"NamePos\": 174,\n                \"ColumnEnd\": 201,\n                \"Name\": {\n                  \"Ident\": {\n                    \"Name\": \"cd\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 174,\n                    \"NameEnd\": 176\n                  },\n                  \"DotIdent\": null\n                },\n                \"Type\": {\n                  \"LeftParenPos\": 183,\n                  \"RightParenPos\": 201,\n                  \"Name\": {\n                    \"Name\": \"Tuple\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 177,\n                    \"NameEnd\": 182\n                  },\n                  \"Columns\": [\n                    {\n                      \"NamePos\": 183,\n                      \"ColumnEnd\": 191,\n                      \"Name\": {\n                        \"Ident\": {\n                          \"Name\": \"c\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 183,\n                          \"NameEnd\": 184\n                        },\n                        \"DotIdent\": null\n                      },\n                      \"Type\": {\n                        \"Name\": {\n                          \"Name\": \"String\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 185,\n                          \"NameEnd\": 191\n                        }\n                      },\n                      \"NotNull\": null,\n                      \"Nullable\": null,\n                      \"DefaultExpr\": null,\n                      \"MaterializedExpr\": null,\n                      \"AliasExpr\": null,\n                      \"Codec\": null,\n                      \"TTL\": null,\n                      \"Comment\": null,\n                      \"CompressionCodec\": null\n                    },\n                    {\n                      \"NamePos\": 193,\n                      \"ColumnEnd\": 201,\n                      \"Name\": {\n                        \"Ident\": {\n                          \"Name\": \"d\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 193,\n                          \"NameEnd\": 194\n                        },\n                        \"DotIdent\": null\n                      },\n                      \"Type\": {\n                        \"Name\": {\n                          \"Name\": \"String\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 195,\n                          \"NameEnd\": 201\n                        }\n                      },\n                      \"NotNull\": null,\n                      \"Nullable\": null,\n                      \"DefaultExpr\": null,\n                      \"MaterializedExpr\": null,\n                      \"AliasExpr\": null,\n                      \"Codec\": null,\n                      \"TTL\": null,\n                      \"Comment\": null,\n                      \"CompressionCodec\": null\n                    }\n                  ]\n                },\n                \"NotNull\": null,\n                \"Nullable\": null,\n                \"DefaultExpr\": null,\n                \"MaterializedExpr\": null,\n                \"AliasExpr\": null,\n                \"Codec\": null,\n                \"TTL\": null,\n                \"Comment\": null,\n                \"CompressionCodec\": null\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 206,\n      \"EngineEnd\": 347,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 234,\n        \"RightParenPos\": 284,\n        \"Items\": {\n          \"ListPos\": 236,\n          \"ListEnd\": 283,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 236,\n                \"LiteralEnd\": 270,\n                \"Literal\": \"/clickhouse/tables/{layer}-{shard}\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 274,\n                \"LiteralEnd\": 283,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": {\n        \"SettingsPos\": 314,\n        \"ListEnd\": 347,\n        \"Items\": [\n          {\n            \"SettingsPos\": 323,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 323,\n              \"NameEnd\": 340\n            },\n            \"Expr\": {\n              \"NumPos\": 343,\n              \"NumEnd\": 347,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 286,\n        \"ListEnd\": 312,\n        \"Items\": [\n          {\n            \"OrderPos\": 286,\n            \"Expr\": {\n              \"LeftParenPos\": 295,\n              \"RightParenPos\": 312,\n              \"Items\": {\n                \"ListPos\": 296,\n                \"ListEnd\": 312,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"tup1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 296,\n                      \"NameEnd\": 300\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"tup2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 302,\n                      \"NameEnd\": 306\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"tup3\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 308,\n                      \"NameEnd\": 312\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_table_with_uuid.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 411,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 31\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 32,\n        \"NameEnd\": 44\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": {\n      \"Value\": {\n        \"LiteralPos\": 51,\n        \"LiteralEnd\": 55,\n        \"Literal\": \"1234\"\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 57,\n      \"Expr\": {\n        \"LiteralPos\": 69,\n        \"LiteralEnd\": 84,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 86,\n      \"SchemaEnd\": 239,\n      \"Columns\": [\n        {\n          \"NamePos\": 92,\n          \"ColumnEnd\": 101,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 92,\n              \"NameEnd\": 94\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 95,\n              \"NameEnd\": 101\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 107,\n          \"ColumnEnd\": 116,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 107,\n              \"NameEnd\": 109\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 110,\n              \"NameEnd\": 116\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 122,\n          \"ColumnEnd\": 131,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 122,\n              \"NameEnd\": 124\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 125,\n              \"NameEnd\": 131\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 137,\n          \"ColumnEnd\": 148,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 137,\n              \"NameEnd\": 139\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 140,\n              \"NameEnd\": 148\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 154,\n          \"ColumnEnd\": 165,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 154,\n              \"NameEnd\": 156\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 157,\n              \"NameEnd\": 165\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 171,\n          \"ColumnEnd\": 191,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 171,\n              \"NameEnd\": 173\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 178,\n            \"RightParenPos\": 191,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 174,\n              \"NameEnd\": 177\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 178,\n                  \"NameEnd\": 184\n                }\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 185,\n                  \"NameEnd\": 191\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 198,\n          \"ColumnEnd\": 207,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 1,\n              \"NamePos\": 198,\n              \"NameEnd\": 200\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 201,\n              \"NameEnd\": 207\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 213,\n          \"ColumnEnd\": 237,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f7\",\n              \"QuoteType\": 1,\n              \"NamePos\": 213,\n              \"NameEnd\": 215\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Datetime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 216,\n              \"NameEnd\": 224\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"Name\": {\n              \"Name\": \"now\",\n              \"QuoteType\": 1,\n              \"NamePos\": 233,\n              \"NameEnd\": 236\n            },\n            \"Params\": {\n              \"LeftParenPos\": 236,\n              \"RightParenPos\": 237,\n              \"Items\": {\n                \"ListPos\": 237,\n                \"ListEnd\": 237,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 241,\n      \"EngineEnd\": 411,\n      \"Name\": \"ReplicatedMergeTree\",\n      \"Params\": {\n        \"LeftParenPos\": 269,\n        \"RightParenPos\": 337,\n        \"Items\": {\n          \"ListPos\": 271,\n          \"ListEnd\": 336,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LiteralPos\": 271,\n                \"LiteralEnd\": 323,\n                \"Literal\": \"/clickhouse/tables/{layer}-{shard}/test/events_local\"\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LiteralPos\": 327,\n                \"LiteralEnd\": 336,\n                \"Literal\": \"{replica}\"\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 365,\n        \"Expr\": {\n          \"ListPos\": 378,\n          \"ListEnd\": 391,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toYYYYMMDD\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 378,\n                  \"NameEnd\": 388\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 388,\n                  \"RightParenPos\": 391,\n                  \"Items\": {\n                    \"ListPos\": 389,\n                    \"ListEnd\": 391,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"f3\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 389,\n                          \"NameEnd\": 391\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 339,\n        \"ListEnd\": 364,\n        \"Items\": [\n          {\n            \"TTLPos\": 339,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"f3\",\n                \"QuoteType\": 1,\n                \"NamePos\": 343,\n                \"NameEnd\": 345\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"IntervalPos\": 348,\n                \"Expr\": {\n                  \"NumPos\": 357,\n                  \"NumEnd\": 358,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                },\n                \"Unit\": {\n                  \"Name\": \"MONTH\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 359,\n                  \"NameEnd\": 364\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 393,\n        \"ListEnd\": 411,\n        \"Items\": [\n          {\n            \"OrderPos\": 393,\n            \"Expr\": {\n              \"LeftParenPos\": 402,\n              \"RightParenPos\": 411,\n              \"Items\": {\n                \"ListPos\": 403,\n                \"ListEnd\": 411,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 403,\n                      \"NameEnd\": 405\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 406,\n                      \"NameEnd\": 408\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 409,\n                      \"NameEnd\": 411\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_user.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 28,\n    \"StatementEnd\": 45,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 40,\n          \"NameEnd\": 45\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 47,\n    \"StatementEnd\": 78,\n    \"IfNotExists\": true,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 73,\n          \"NameEnd\": 78\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 80,\n    \"StatementEnd\": 108,\n    \"IfNotExists\": false,\n    \"OrReplace\": true,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 103,\n          \"NameEnd\": 108\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 110,\n    \"StatementEnd\": 134,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user4\",\n          \"QuoteType\": 1,\n          \"NamePos\": 122,\n          \"NameEnd\": 127\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"user5\",\n          \"QuoteType\": 1,\n          \"NamePos\": 129,\n          \"NameEnd\": 134\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 172,\n    \"StatementEnd\": 205,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user6\",\n          \"QuoteType\": 1,\n          \"NamePos\": 184,\n          \"NameEnd\": 189\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 190,\n      \"AuthEnd\": 205,\n      \"NotIdentified\": true,\n      \"AuthType\": \"\",\n      \"AuthValue\": null,\n      \"LdapServer\": null,\n      \"KerberosRealm\": null,\n      \"IsKerberos\": false\n    },\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 206,\n    \"StatementEnd\": 274,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user7\",\n          \"QuoteType\": 1,\n          \"NamePos\": 218,\n          \"NameEnd\": 223\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 224,\n      \"AuthEnd\": 274,\n      \"NotIdentified\": false,\n      \"AuthType\": \"plaintext_password\",\n      \"AuthValue\": {\n        \"LiteralPos\": 263,\n        \"LiteralEnd\": 274,\n        \"Literal\": \"password123\"\n      },\n      \"LdapServer\": null,\n      \"KerberosRealm\": null,\n      \"IsKerberos\": false\n    },\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 277,\n    \"StatementEnd\": 338,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user8\",\n          \"QuoteType\": 1,\n          \"NamePos\": 289,\n          \"NameEnd\": 294\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 295,\n      \"AuthEnd\": 338,\n      \"NotIdentified\": false,\n      \"AuthType\": \"sha256_password\",\n      \"AuthValue\": {\n        \"LiteralPos\": 331,\n        \"LiteralEnd\": 338,\n        \"Literal\": \"hash123\"\n      },\n      \"LdapServer\": null,\n      \"KerberosRealm\": null,\n      \"IsKerberos\": false\n    },\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 341,\n    \"StatementEnd\": 399,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user9\",\n          \"QuoteType\": 1,\n          \"NamePos\": 353,\n          \"NameEnd\": 358\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 359,\n      \"AuthEnd\": 399,\n      \"NotIdentified\": false,\n      \"AuthType\": \"\",\n      \"AuthValue\": null,\n      \"LdapServer\": {\n        \"LiteralPos\": 388,\n        \"LiteralEnd\": 399,\n        \"Literal\": \"ldap_server\"\n      },\n      \"KerberosRealm\": null,\n      \"IsKerberos\": false\n    },\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 402,\n    \"StatementEnd\": 446,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user10\",\n          \"QuoteType\": 1,\n          \"NamePos\": 414,\n          \"NameEnd\": 420\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 421,\n      \"AuthEnd\": 446,\n      \"NotIdentified\": false,\n      \"AuthType\": \"\",\n      \"AuthValue\": null,\n      \"LdapServer\": null,\n      \"KerberosRealm\": null,\n      \"IsKerberos\": true\n    },\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 447,\n    \"StatementEnd\": 509,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user11\",\n          \"QuoteType\": 1,\n          \"NamePos\": 459,\n          \"NameEnd\": 465\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 466,\n      \"AuthEnd\": 509,\n      \"NotIdentified\": false,\n      \"AuthType\": \"\",\n      \"AuthValue\": null,\n      \"LdapServer\": null,\n      \"KerberosRealm\": {\n        \"LiteralPos\": 498,\n        \"LiteralEnd\": 509,\n        \"Literal\": \"EXAMPLE.COM\"\n      },\n      \"IsKerberos\": true\n    },\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 545,\n    \"StatementEnd\": 596,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user33\",\n          \"QuoteType\": 1,\n          \"NamePos\": 557,\n          \"NameEnd\": 563\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": {\n      \"LiteralPos\": 577,\n      \"LiteralEnd\": 596,\n      \"Literal\": \"2026-12-12 00:00:00\"\n    },\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 599,\n    \"StatementEnd\": 693,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user34\",\n          \"QuoteType\": 1,\n          \"NamePos\": 611,\n          \"NameEnd\": 617\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 618,\n      \"AuthEnd\": 668,\n      \"NotIdentified\": false,\n      \"AuthType\": \"plaintext_password\",\n      \"AuthValue\": {\n        \"LiteralPos\": 657,\n        \"LiteralEnd\": 668,\n        \"Literal\": \"password123\"\n      },\n      \"LdapServer\": null,\n      \"KerberosRealm\": null,\n      \"IsKerberos\": false\n    },\n    \"ValidUntil\": {\n      \"LiteralPos\": 683,\n      \"LiteralEnd\": 693,\n      \"Literal\": \"2026-06-15\"\n    },\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 696,\n    \"StatementEnd\": 736,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user35\",\n          \"QuoteType\": 1,\n          \"NamePos\": 708,\n          \"NameEnd\": 714\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": {\n      \"LiteralPos\": 728,\n      \"LiteralEnd\": 736,\n      \"Literal\": \"infinity\"\n    },\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 778,\n    \"StatementEnd\": 808,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user12\",\n          \"QuoteType\": 1,\n          \"NamePos\": 790,\n          \"NameEnd\": 796\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 797,\n        \"HostEnd\": 808,\n        \"HostType\": \"LOCAL\",\n        \"HostValue\": null\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 809,\n    \"StatementEnd\": 837,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user13\",\n          \"QuoteType\": 1,\n          \"NamePos\": 821,\n          \"NameEnd\": 827\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 828,\n        \"HostEnd\": 837,\n        \"HostType\": \"ANY\",\n        \"HostValue\": null\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 838,\n    \"StatementEnd\": 867,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user14\",\n          \"QuoteType\": 1,\n          \"NamePos\": 850,\n          \"NameEnd\": 856\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 857,\n        \"HostEnd\": 867,\n        \"HostType\": \"NONE\",\n        \"HostValue\": null\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 868,\n    \"StatementEnd\": 907,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user15\",\n          \"QuoteType\": 1,\n          \"NamePos\": 880,\n          \"NameEnd\": 886\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 887,\n        \"HostEnd\": 907,\n        \"HostType\": \"NAME\",\n        \"HostValue\": {\n          \"LiteralPos\": 898,\n          \"LiteralEnd\": 907,\n          \"Literal\": \"localhost\"\n        }\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 910,\n    \"StatementEnd\": 958,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user16\",\n          \"QuoteType\": 1,\n          \"NamePos\": 922,\n          \"NameEnd\": 928\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 929,\n        \"HostEnd\": 958,\n        \"HostType\": \"REGEXP\",\n        \"HostValue\": {\n          \"LiteralPos\": 942,\n          \"LiteralEnd\": 958,\n          \"Literal\": \".*\\\\.example\\\\.com\"\n        }\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 961,\n    \"StatementEnd\": 1000,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user17\",\n          \"QuoteType\": 1,\n          \"NamePos\": 973,\n          \"NameEnd\": 979\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 980,\n        \"HostEnd\": 1000,\n        \"HostType\": \"IP\",\n        \"HostValue\": {\n          \"LiteralPos\": 989,\n          \"LiteralEnd\": 1000,\n          \"Literal\": \"192.168.1.1\"\n        }\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1003,\n    \"StatementEnd\": 1038,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user18\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1015,\n          \"NameEnd\": 1021\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": [\n      {\n        \"HostPos\": 1022,\n        \"HostEnd\": 1038,\n        \"HostType\": \"LIKE\",\n        \"HostValue\": {\n          \"LiteralPos\": 1033,\n          \"LiteralEnd\": 1038,\n          \"Literal\": \"test%\"\n        }\n      }\n    ],\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1076,\n    \"StatementEnd\": 1113,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user19\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1088,\n          \"NameEnd\": 1094\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": {\n      \"DefaultPos\": 1095,\n      \"DefaultEnd\": 1113,\n      \"Roles\": [\n        {\n          \"Name\": {\n            \"Name\": \"role1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1108,\n            \"NameEnd\": 1113\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"None\": false\n    },\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1115,\n    \"StatementEnd\": 1159,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user20\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1127,\n          \"NameEnd\": 1133\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": {\n      \"DefaultPos\": 1134,\n      \"DefaultEnd\": 1159,\n      \"Roles\": [\n        {\n          \"Name\": {\n            \"Name\": \"role1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1147,\n            \"NameEnd\": 1152\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        {\n          \"Name\": {\n            \"Name\": \"role2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1154,\n            \"NameEnd\": 1159\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"None\": false\n    },\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1161,\n    \"StatementEnd\": 1198,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user21\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1173,\n          \"NameEnd\": 1179\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": {\n      \"DefaultPos\": 1180,\n      \"DefaultEnd\": 1198,\n      \"Roles\": null,\n      \"None\": true\n    },\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1237,\n    \"StatementEnd\": 1280,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user22\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1249,\n          \"NameEnd\": 1255\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": {\n      \"Name\": \"test_db\",\n      \"QuoteType\": 1,\n      \"NamePos\": 1273,\n      \"NameEnd\": 1280\n    },\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1282,\n    \"StatementEnd\": 1323,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user23\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1294,\n          \"NameEnd\": 1300\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": true,\n    \"Grantees\": null,\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1354,\n    \"StatementEnd\": 1387,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user24\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1366,\n          \"NameEnd\": 1372\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": {\n      \"GranteesPos\": 1373,\n      \"GranteesEnd\": 1387,\n      \"Grantees\": [\n        {\n          \"Name\": {\n            \"Name\": \"user1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1382,\n            \"NameEnd\": 1387\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"ExceptUsers\": null,\n      \"Any\": false,\n      \"None\": false\n    },\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1389,\n    \"StatementEnd\": 1429,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user25\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1401,\n          \"NameEnd\": 1407\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": {\n      \"GranteesPos\": 1408,\n      \"GranteesEnd\": 1429,\n      \"Grantees\": [\n        {\n          \"Name\": {\n            \"Name\": \"user1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1417,\n            \"NameEnd\": 1422\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        {\n          \"Name\": {\n            \"Name\": \"user2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1424,\n            \"NameEnd\": 1429\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"ExceptUsers\": null,\n      \"Any\": false,\n      \"None\": false\n    },\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1431,\n    \"StatementEnd\": 1463,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user26\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1443,\n          \"NameEnd\": 1449\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": {\n      \"GranteesPos\": 1450,\n      \"GranteesEnd\": 1463,\n      \"Grantees\": null,\n      \"ExceptUsers\": null,\n      \"Any\": true,\n      \"None\": false\n    },\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1464,\n    \"StatementEnd\": 1497,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user27\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1476,\n          \"NameEnd\": 1482\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": {\n      \"GranteesPos\": 1483,\n      \"GranteesEnd\": 1497,\n      \"Grantees\": null,\n      \"ExceptUsers\": null,\n      \"Any\": false,\n      \"None\": true\n    },\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1498,\n    \"StatementEnd\": 1551,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user28\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1510,\n          \"NameEnd\": 1516\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": {\n      \"GranteesPos\": 1517,\n      \"GranteesEnd\": 1551,\n      \"Grantees\": [\n        {\n          \"Name\": {\n            \"Name\": \"user1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1526,\n            \"NameEnd\": 1531\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        {\n          \"Name\": {\n            \"Name\": \"user2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1533,\n            \"NameEnd\": 1538\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"ExceptUsers\": [\n        {\n          \"Name\": {\n            \"Name\": \"user3\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1546,\n            \"NameEnd\": 1551\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"Any\": false,\n      \"None\": false\n    },\n    \"Settings\": null\n  },\n  {\n    \"CreatePos\": 1583,\n    \"StatementEnd\": 1635,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user29\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1595,\n          \"NameEnd\": 1601\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1611,\n              \"NameEnd\": 1627\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 1628,\n              \"NumEnd\": 1635,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 1637,\n    \"StatementEnd\": 1681,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user30\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1649,\n          \"NameEnd\": 1655\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"PROFILE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1665,\n              \"NameEnd\": 1672\n            },\n            \"Operation\": \"\",\n            \"Value\": {\n              \"LiteralPos\": 1674,\n              \"LiteralEnd\": 1681,\n              \"Literal\": \"default\"\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 1684,\n    \"StatementEnd\": 1748,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user31\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1696,\n          \"NameEnd\": 1702\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": null,\n    \"ValidUntil\": null,\n    \"Hosts\": null,\n    \"DefaultRole\": null,\n    \"DefaultDatabase\": null,\n    \"DefaultDbNone\": false,\n    \"Grantees\": null,\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"readonly\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1712,\n              \"NameEnd\": 1720\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 1721,\n              \"NumEnd\": 1722,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1724,\n              \"NameEnd\": 1740\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 1741,\n              \"NumEnd\": 1748,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  },\n  {\n    \"CreatePos\": 1796,\n    \"StatementEnd\": 2070,\n    \"IfNotExists\": false,\n    \"OrReplace\": false,\n    \"UserNames\": [\n      {\n        \"Name\": {\n          \"Name\": \"user32\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1808,\n          \"NameEnd\": 1814\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"Authentication\": {\n      \"AuthPos\": 1819,\n      \"AuthEnd\": 1866,\n      \"NotIdentified\": false,\n      \"AuthType\": \"plaintext_password\",\n      \"AuthValue\": {\n        \"LiteralPos\": 1858,\n        \"LiteralEnd\": 1866,\n        \"Literal\": \"password\"\n      },\n      \"LdapServer\": null,\n      \"KerberosRealm\": null,\n      \"IsKerberos\": false\n    },\n    \"ValidUntil\": {\n      \"LiteralPos\": 1885,\n      \"LiteralEnd\": 1895,\n      \"Literal\": \"2025-12-31\"\n    },\n    \"Hosts\": [\n      {\n        \"HostPos\": 1901,\n        \"HostEnd\": 1921,\n        \"HostType\": \"NAME\",\n        \"HostValue\": {\n          \"LiteralPos\": 1912,\n          \"LiteralEnd\": 1921,\n          \"Literal\": \"localhost\"\n        }\n      }\n    ],\n    \"DefaultRole\": {\n      \"DefaultPos\": 1927,\n      \"DefaultEnd\": 1952,\n      \"Roles\": [\n        {\n          \"Name\": {\n            \"Name\": \"role1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1940,\n            \"NameEnd\": 1945\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        {\n          \"Name\": {\n            \"Name\": \"role2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1947,\n            \"NameEnd\": 1952\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"None\": false\n    },\n    \"DefaultDatabase\": {\n      \"Name\": \"test_db\",\n      \"QuoteType\": 1,\n      \"NamePos\": 1974,\n      \"NameEnd\": 1981\n    },\n    \"DefaultDbNone\": false,\n    \"Grantees\": {\n      \"GranteesPos\": 1986,\n      \"GranteesEnd\": 2020,\n      \"Grantees\": [\n        {\n          \"Name\": {\n            \"Name\": \"user1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 1995,\n            \"NameEnd\": 2000\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        },\n        {\n          \"Name\": {\n            \"Name\": \"user2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 2002,\n            \"NameEnd\": 2007\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"ExceptUsers\": [\n        {\n          \"Name\": {\n            \"Name\": \"user3\",\n            \"QuoteType\": 1,\n            \"NamePos\": 2015,\n            \"NameEnd\": 2020\n          },\n          \"Scope\": null,\n          \"OnCluster\": null\n        }\n      ],\n      \"Any\": false,\n      \"None\": false\n    },\n    \"Settings\": [\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"max_memory_usage\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2034,\n              \"NameEnd\": 2050\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 2051,\n              \"NumEnd\": 2058,\n              \"Literal\": \"5000000\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      },\n      {\n        \"SettingPairs\": [\n          {\n            \"Name\": {\n              \"Name\": \"readonly\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2060,\n              \"NameEnd\": 2068\n            },\n            \"Operation\": \"=\",\n            \"Value\": {\n              \"NumPos\": 2069,\n              \"NumEnd\": 2070,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ],\n        \"Modifier\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_view_basic.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 104,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"my_view\",\n        \"QuoteType\": 1,\n        \"NamePos\": 26,\n        \"NameEnd\": 33\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 33,\n      \"SchemaEnd\": 58,\n      \"Columns\": [\n        {\n          \"NamePos\": 34,\n          \"ColumnEnd\": 45,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"col1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 34,\n              \"NameEnd\": 38\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 45\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 47,\n          \"ColumnEnd\": 58,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"col2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 47,\n              \"NameEnd\": 51\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 52,\n              \"NameEnd\": 58\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Comment\": null,\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 63,\n        \"StatementEnd\": 104,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 74,\n              \"NameEnd\": 76\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 82,\n              \"NameEnd\": 86\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 87,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 96,\n              \"TableEnd\": 104,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"my_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 96,\n                  \"NameEnd\": 104\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 104,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_view_on_cluster_with_uuid.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 199,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"cluster_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 26,\n        \"NameEnd\": 38\n      },\n      \"Table\": {\n        \"Name\": \"my_view\",\n        \"QuoteType\": 1,\n        \"NamePos\": 39,\n        \"NameEnd\": 46\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": {\n      \"Value\": {\n        \"LiteralPos\": 61,\n        \"LiteralEnd\": 97,\n        \"Literal\": \"3493e374-e2bb-481b-b493-e374e2bb981b\"\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 107,\n      \"Expr\": {\n        \"LiteralPos\": 119,\n        \"LiteralEnd\": 129,\n        \"Literal\": \"my_cluster\"\n      }\n    },\n    \"TableSchema\": null,\n    \"Comment\": null,\n    \"SubQuery\": {\n      \"HasParen\": true,\n      \"Select\": {\n        \"SelectPos\": 140,\n        \"StatementEnd\": 199,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"column1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 151,\n              \"NameEnd\": 158\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"column2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 164,\n              \"NameEnd\": 171\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 176,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 185,\n              \"TableEnd\": 199,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"my_other_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 185,\n                  \"NameEnd\": 199\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 199,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_view_with_comment.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 156,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 26,\n        \"NameEnd\": 28\n      },\n      \"Table\": {\n        \"Name\": \"my_view\",\n        \"QuoteType\": 1,\n        \"NamePos\": 29,\n        \"NameEnd\": 36\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 37,\n      \"SchemaEnd\": 73,\n      \"Columns\": [\n        {\n          \"NamePos\": 44,\n          \"ColumnEnd\": 53,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 3,\n              \"NamePos\": 44,\n              \"NameEnd\": 46\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"Int64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 48,\n              \"NameEnd\": 53\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 60,\n          \"ColumnEnd\": 72,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 3,\n              \"NamePos\": 60,\n              \"NameEnd\": 64\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 72\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Comment\": {\n      \"LiteralPos\": 84,\n      \"LiteralEnd\": 111,\n      \"Literal\": \"{\\\"blueprint_hash\\\":\\\"abc123\\\"}\"\n    },\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 116,\n        \"StatementEnd\": 156,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 127,\n              \"NameEnd\": 129\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 135,\n              \"NameEnd\": 139\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 140,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 145,\n              \"TableEnd\": 156,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": {\n                  \"Name\": \"db\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 145,\n                  \"NameEnd\": 147\n                },\n                \"Table\": {\n                  \"Name\": \"my_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 148,\n                  \"NameEnd\": 156\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 156,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/create_with_time_zone.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 2003,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 27,\n        \"NameEnd\": 31\n      },\n      \"Table\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 32,\n        \"NameEnd\": 34\n      }\n    },\n    \"IfNotExists\": true,\n    \"UUID\": null,\n    \"OnCluster\": {\n      \"OnPos\": 35,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 46,\n        \"NameEnd\": 61\n      }\n    },\n    \"TableSchema\": {\n      \"SchemaPos\": 62,\n      \"SchemaEnd\": 1756,\n      \"Columns\": [\n        {\n          \"NamePos\": 69,\n          \"ColumnEnd\": 258,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 3,\n              \"NamePos\": 69,\n              \"NameEnd\": 71\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 79,\n            \"RightParenPos\": 237,\n            \"Name\": {\n              \"Name\": \"Array\",\n              \"QuoteType\": 1,\n              \"NamePos\": 73,\n              \"NameEnd\": 78\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 94,\n                \"RightParenPos\": 236,\n                \"Name\": {\n                  \"Name\": \"Tuple\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 79,\n                  \"NameEnd\": 84\n                },\n                \"Columns\": [\n                  {\n                    \"NamePos\": 94,\n                    \"ColumnEnd\": 117,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f00\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 94,\n                        \"NameEnd\": 97\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 109,\n                      \"RightParenPos\": 117,\n                      \"Name\": {\n                        \"Name\": \"DateTime64\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 98,\n                        \"NameEnd\": 108\n                      },\n                      \"Params\": [\n                        {\n                          \"NumPos\": 109,\n                          \"NumEnd\": 110,\n                          \"Literal\": \"9\",\n                          \"Base\": 10\n                        },\n                        {\n                          \"LiteralPos\": 113,\n                          \"LiteralEnd\": 116,\n                          \"Literal\": \"UTC\"\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 128,\n                    \"ColumnEnd\": 138,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f01\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 128,\n                        \"NameEnd\": 131\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"String\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 132,\n                        \"NameEnd\": 138\n                      }\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 148,\n                    \"ColumnEnd\": 170,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f02\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 148,\n                        \"NameEnd\": 151\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 156,\n                      \"RightParenPos\": 170,\n                      \"Name\": {\n                        \"Name\": \"Map\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 152,\n                        \"NameEnd\": 155\n                      },\n                      \"Params\": [\n                        {\n                          \"Name\": {\n                            \"Name\": \"String\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 156,\n                            \"NameEnd\": 162\n                          }\n                        },\n                        {\n                          \"Name\": {\n                            \"Name\": \"String\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 164,\n                            \"NameEnd\": 170\n                          }\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 181,\n                    \"ColumnEnd\": 204,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f03\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 181,\n                        \"NameEnd\": 184\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 189,\n                      \"RightParenPos\": 204,\n                      \"Name\": {\n                        \"Name\": \"Map\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 185,\n                        \"NameEnd\": 188\n                      },\n                      \"Params\": [\n                        {\n                          \"Name\": {\n                            \"Name\": \"String\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 189,\n                            \"NameEnd\": 195\n                          }\n                        },\n                        {\n                          \"Name\": {\n                            \"Name\": \"Float64\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 197,\n                            \"NameEnd\": 204\n                          }\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 215,\n                    \"ColumnEnd\": 235,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f04\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 215,\n                        \"NameEnd\": 218\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 223,\n                      \"RightParenPos\": 235,\n                      \"Name\": {\n                        \"Name\": \"Map\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 219,\n                        \"NameEnd\": 222\n                      },\n                      \"Params\": [\n                        {\n                          \"Name\": {\n                            \"Name\": \"String\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 223,\n                            \"NameEnd\": 229\n                          }\n                        },\n                        {\n                          \"Name\": {\n                            \"Name\": \"BOOL\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 231,\n                            \"NameEnd\": 235\n                          }\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  }\n                ]\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 239,\n            \"RightParenPos\": 258,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 245,\n              \"NameEnd\": 249\n            },\n            \"Level\": {\n              \"NumPos\": 249,\n              \"NumEnd\": 251,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 265,\n          \"ColumnEnd\": 296,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 3,\n              \"NamePos\": 265,\n              \"NameEnd\": 267\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 269,\n              \"NameEnd\": 275\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 276,\n            \"RightParenPos\": 296,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 282,\n              \"NameEnd\": 287\n            },\n            \"TypeLevel\": {\n              \"NumPos\": 287,\n              \"NumEnd\": 289,\n              \"Literal\": \"8\",\n              \"Base\": 10\n            },\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 292,\n              \"NameEnd\": 295\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 303,\n          \"ColumnEnd\": 333,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 3,\n              \"NamePos\": 303,\n              \"NameEnd\": 305\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 319,\n            \"RightParenPos\": 321,\n            \"Name\": {\n              \"Name\": \"FixedString\",\n              \"QuoteType\": 1,\n              \"NamePos\": 307,\n              \"NameEnd\": 318\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 319,\n                \"NumEnd\": 321,\n                \"Literal\": \"16\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 323,\n            \"RightParenPos\": 333,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 329,\n              \"NameEnd\": 332\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 340,\n          \"ColumnEnd\": 369,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 3,\n              \"NamePos\": 340,\n              \"NameEnd\": 342\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 356,\n            \"RightParenPos\": 357,\n            \"Name\": {\n              \"Name\": \"FixedString\",\n              \"QuoteType\": 1,\n              \"NamePos\": 344,\n              \"NameEnd\": 355\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 356,\n                \"NumEnd\": 357,\n                \"Literal\": \"8\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 359,\n            \"RightParenPos\": 369,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 365,\n              \"NameEnd\": 368\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 376,\n          \"ColumnEnd\": 405,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f4\",\n              \"QuoteType\": 3,\n              \"NamePos\": 376,\n              \"NameEnd\": 378\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 392,\n            \"RightParenPos\": 393,\n            \"Name\": {\n              \"Name\": \"FixedString\",\n              \"QuoteType\": 1,\n              \"NamePos\": 380,\n              \"NameEnd\": 391\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 392,\n                \"NumEnd\": 393,\n                \"Literal\": \"8\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 395,\n            \"RightParenPos\": 405,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 401,\n              \"NameEnd\": 404\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 412,\n          \"ColumnEnd\": 457,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 3,\n              \"NamePos\": 412,\n              \"NameEnd\": 414\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 427,\n            \"RightParenPos\": 435,\n            \"Name\": {\n              \"Name\": \"DateTime64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 416,\n              \"NameEnd\": 426\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 427,\n                \"NumEnd\": 428,\n                \"Literal\": \"9\",\n                \"Base\": 10\n              },\n              {\n                \"LiteralPos\": 431,\n                \"LiteralEnd\": 434,\n                \"Literal\": \"UTC\"\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 437,\n            \"RightParenPos\": 457,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 443,\n              \"NameEnd\": 448\n            },\n            \"TypeLevel\": {\n              \"NumPos\": 448,\n              \"NumEnd\": 450,\n              \"Literal\": \"8\",\n              \"Base\": 10\n            },\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 453,\n              \"NameEnd\": 456\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 464,\n          \"ColumnEnd\": 495,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f6\",\n              \"QuoteType\": 3,\n              \"NamePos\": 464,\n              \"NameEnd\": 466\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 468,\n              \"NameEnd\": 474\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 475,\n            \"RightParenPos\": 495,\n            \"Type\": {\n              \"Name\": \"Delta\",\n              \"QuoteType\": 1,\n              \"NamePos\": 481,\n              \"NameEnd\": 486\n            },\n            \"TypeLevel\": {\n              \"NumPos\": 486,\n              \"NumEnd\": 488,\n              \"Literal\": \"8\",\n              \"Base\": 10\n            },\n            \"Name\": {\n              \"Name\": \"LZ4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 491,\n              \"NameEnd\": 494\n            },\n            \"Level\": null\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 502,\n          \"ColumnEnd\": 543,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f7\",\n              \"QuoteType\": 3,\n              \"NamePos\": 502,\n              \"NameEnd\": 504\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 521,\n            \"RightParenPos\": 527,\n            \"Name\": {\n              \"Name\": \"LowCardinality\",\n              \"QuoteType\": 1,\n              \"NamePos\": 506,\n              \"NameEnd\": 520\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 521,\n                  \"NameEnd\": 527\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 529,\n            \"RightParenPos\": 543,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 535,\n              \"NameEnd\": 539\n            },\n            \"Level\": {\n              \"NumPos\": 539,\n              \"NumEnd\": 541,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 550,\n          \"ColumnEnd\": 575,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f8\",\n              \"QuoteType\": 3,\n              \"NamePos\": 550,\n              \"NameEnd\": 552\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 554,\n              \"NameEnd\": 560\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 561,\n            \"RightParenPos\": 575,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 567,\n              \"NameEnd\": 571\n            },\n            \"Level\": {\n              \"NumPos\": 571,\n              \"NumEnd\": 573,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 582,\n          \"ColumnEnd\": 623,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f9\",\n              \"QuoteType\": 3,\n              \"NamePos\": 582,\n              \"NameEnd\": 584\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 601,\n            \"RightParenPos\": 607,\n            \"Name\": {\n              \"Name\": \"LowCardinality\",\n              \"QuoteType\": 1,\n              \"NamePos\": 586,\n              \"NameEnd\": 600\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 601,\n                  \"NameEnd\": 607\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 609,\n            \"RightParenPos\": 623,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 615,\n              \"NameEnd\": 619\n            },\n            \"Level\": {\n              \"NumPos\": 619,\n              \"NumEnd\": 621,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 630,\n          \"ColumnEnd\": 656,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f10\",\n              \"QuoteType\": 3,\n              \"NamePos\": 630,\n              \"NameEnd\": 633\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 635,\n              \"NameEnd\": 641\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 642,\n            \"RightParenPos\": 656,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 648,\n              \"NameEnd\": 652\n            },\n            \"Level\": {\n              \"NumPos\": 652,\n              \"NumEnd\": 654,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 663,\n          \"ColumnEnd\": 705,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f11\",\n              \"QuoteType\": 3,\n              \"NamePos\": 663,\n              \"NameEnd\": 666\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 683,\n            \"RightParenPos\": 689,\n            \"Name\": {\n              \"Name\": \"LowCardinality\",\n              \"QuoteType\": 1,\n              \"NamePos\": 668,\n              \"NameEnd\": 682\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 683,\n                  \"NameEnd\": 689\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 691,\n            \"RightParenPos\": 705,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 697,\n              \"NameEnd\": 701\n            },\n            \"Level\": {\n              \"NumPos\": 701,\n              \"NumEnd\": 703,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 712,\n          \"ColumnEnd\": 754,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f12\",\n              \"QuoteType\": 3,\n              \"NamePos\": 712,\n              \"NameEnd\": 715\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 732,\n            \"RightParenPos\": 738,\n            \"Name\": {\n              \"Name\": \"LowCardinality\",\n              \"QuoteType\": 1,\n              \"NamePos\": 717,\n              \"NameEnd\": 731\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 732,\n                  \"NameEnd\": 738\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 740,\n            \"RightParenPos\": 754,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 746,\n              \"NameEnd\": 750\n            },\n            \"Level\": {\n              \"NumPos\": 750,\n              \"NumEnd\": 752,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 761,\n          \"ColumnEnd\": 787,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f13\",\n              \"QuoteType\": 3,\n              \"NamePos\": 761,\n              \"NameEnd\": 764\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 766,\n              \"NameEnd\": 772\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 773,\n            \"RightParenPos\": 787,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 779,\n              \"NameEnd\": 783\n            },\n            \"Level\": {\n              \"NumPos\": 783,\n              \"NumEnd\": 785,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 794,\n          \"ColumnEnd\": 849,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f14\",\n              \"QuoteType\": 3,\n              \"NamePos\": 794,\n              \"NameEnd\": 797\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 803,\n            \"RightParenPos\": 833,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 799,\n              \"NameEnd\": 802\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 818,\n                \"RightParenPos\": 824,\n                \"Name\": {\n                  \"Name\": \"LowCardinality\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 803,\n                  \"NameEnd\": 817\n                },\n                \"Params\": [\n                  {\n                    \"Name\": {\n                      \"Name\": \"String\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 818,\n                      \"NameEnd\": 824\n                    }\n                  }\n                ]\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 827,\n                  \"NameEnd\": 833\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 835,\n            \"RightParenPos\": 849,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 841,\n              \"NameEnd\": 845\n            },\n            \"Level\": {\n              \"NumPos\": 845,\n              \"NumEnd\": 847,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 856,\n          \"ColumnEnd\": 911,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f15\",\n              \"QuoteType\": 3,\n              \"NamePos\": 856,\n              \"NameEnd\": 859\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 865,\n            \"RightParenPos\": 895,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 861,\n              \"NameEnd\": 864\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 880,\n                \"RightParenPos\": 886,\n                \"Name\": {\n                  \"Name\": \"LowCardinality\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 865,\n                  \"NameEnd\": 879\n                },\n                \"Params\": [\n                  {\n                    \"Name\": {\n                      \"Name\": \"String\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 880,\n                      \"NameEnd\": 886\n                    }\n                  }\n                ]\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 889,\n                  \"NameEnd\": 895\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 897,\n            \"RightParenPos\": 911,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 903,\n              \"NameEnd\": 907\n            },\n            \"Level\": {\n              \"NumPos\": 907,\n              \"NumEnd\": 909,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 918,\n          \"ColumnEnd\": 974,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f16\",\n              \"QuoteType\": 3,\n              \"NamePos\": 918,\n              \"NameEnd\": 921\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 927,\n            \"RightParenPos\": 958,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 923,\n              \"NameEnd\": 926\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 942,\n                \"RightParenPos\": 948,\n                \"Name\": {\n                  \"Name\": \"LowCardinality\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 927,\n                  \"NameEnd\": 941\n                },\n                \"Params\": [\n                  {\n                    \"Name\": {\n                      \"Name\": \"String\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 942,\n                      \"NameEnd\": 948\n                    }\n                  }\n                ]\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"Float64\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 951,\n                  \"NameEnd\": 958\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 960,\n            \"RightParenPos\": 974,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 966,\n              \"NameEnd\": 970\n            },\n            \"Level\": {\n              \"NumPos\": 970,\n              \"NumEnd\": 972,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 981,\n          \"ColumnEnd\": 1034,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f17\",\n              \"QuoteType\": 3,\n              \"NamePos\": 981,\n              \"NameEnd\": 984\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 990,\n            \"RightParenPos\": 1018,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 986,\n              \"NameEnd\": 989\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 1005,\n                \"RightParenPos\": 1011,\n                \"Name\": {\n                  \"Name\": \"LowCardinality\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 990,\n                  \"NameEnd\": 1004\n                },\n                \"Params\": [\n                  {\n                    \"Name\": {\n                      \"Name\": \"String\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1005,\n                      \"NameEnd\": 1011\n                    }\n                  }\n                ]\n              },\n              {\n                \"Name\": {\n                  \"Name\": \"BOOL\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 1014,\n                  \"NameEnd\": 1018\n                }\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 1020,\n            \"RightParenPos\": 1034,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1026,\n              \"NameEnd\": 1030\n            },\n            \"Level\": {\n              \"NumPos\": 1030,\n              \"NumEnd\": 1032,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 1041,\n          \"ColumnEnd\": 1188,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f18\",\n              \"QuoteType\": 3,\n              \"NamePos\": 1041,\n              \"NameEnd\": 1044\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"LeftParenPos\": 1052,\n            \"RightParenPos\": 1172,\n            \"Name\": {\n              \"Name\": \"Array\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1046,\n              \"NameEnd\": 1051\n            },\n            \"Params\": [\n              {\n                \"LeftParenPos\": 1067,\n                \"RightParenPos\": 1171,\n                \"Name\": {\n                  \"Name\": \"Tuple\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 1052,\n                  \"NameEnd\": 1057\n                },\n                \"Columns\": [\n                  {\n                    \"NamePos\": 1067,\n                    \"ColumnEnd\": 1086,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f180\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1067,\n                        \"NameEnd\": 1071\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 1084,\n                      \"RightParenPos\": 1086,\n                      \"Name\": {\n                        \"Name\": \"FixedString\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1072,\n                        \"NameEnd\": 1083\n                      },\n                      \"Params\": [\n                        {\n                          \"NumPos\": 1084,\n                          \"NumEnd\": 1086,\n                          \"Literal\": \"16\",\n                          \"Base\": 10\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 1097,\n                    \"ColumnEnd\": 1115,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f181\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1097,\n                        \"NameEnd\": 1101\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 1114,\n                      \"RightParenPos\": 1115,\n                      \"Name\": {\n                        \"Name\": \"FixedString\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1102,\n                        \"NameEnd\": 1113\n                      },\n                      \"Params\": [\n                        {\n                          \"NumPos\": 1114,\n                          \"NumEnd\": 1115,\n                          \"Literal\": \"8\",\n                          \"Base\": 10\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 1126,\n                    \"ColumnEnd\": 1137,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f182\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1126,\n                        \"NameEnd\": 1130\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"String\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1131,\n                        \"NameEnd\": 1137\n                      }\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  },\n                  {\n                    \"NamePos\": 1147,\n                    \"ColumnEnd\": 1170,\n                    \"Name\": {\n                      \"Ident\": {\n                        \"Name\": \"f183\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1147,\n                        \"NameEnd\": 1151\n                      },\n                      \"DotIdent\": null\n                    },\n                    \"Type\": {\n                      \"LeftParenPos\": 1156,\n                      \"RightParenPos\": 1170,\n                      \"Name\": {\n                        \"Name\": \"Map\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1152,\n                        \"NameEnd\": 1155\n                      },\n                      \"Params\": [\n                        {\n                          \"Name\": {\n                            \"Name\": \"String\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 1156,\n                            \"NameEnd\": 1162\n                          }\n                        },\n                        {\n                          \"Name\": {\n                            \"Name\": \"String\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 1164,\n                            \"NameEnd\": 1170\n                          }\n                        }\n                      ]\n                    },\n                    \"NotNull\": null,\n                    \"Nullable\": null,\n                    \"DefaultExpr\": null,\n                    \"MaterializedExpr\": null,\n                    \"AliasExpr\": null,\n                    \"Codec\": null,\n                    \"TTL\": null,\n                    \"Comment\": null,\n                    \"CompressionCodec\": null\n                  }\n                ]\n              }\n            ]\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 1174,\n            \"RightParenPos\": 1188,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1180,\n              \"NameEnd\": 1184\n            },\n            \"Level\": {\n              \"NumPos\": 1184,\n              \"NumEnd\": 1186,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 1199,\n          \"ColumnEnd\": 1226,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f184\",\n              \"QuoteType\": 3,\n              \"NamePos\": 1199,\n              \"NameEnd\": 1203\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1205,\n              \"NameEnd\": 1211\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 1212,\n            \"RightParenPos\": 1226,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1218,\n              \"NameEnd\": 1222\n            },\n            \"Level\": {\n              \"NumPos\": 1222,\n              \"NumEnd\": 1224,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 1237,\n          \"ColumnEnd\": 1264,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f185\",\n              \"QuoteType\": 3,\n              \"NamePos\": 1237,\n              \"NameEnd\": 1241\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1243,\n              \"NameEnd\": 1249\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 1250,\n            \"RightParenPos\": 1264,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1256,\n              \"NameEnd\": 1260\n            },\n            \"Level\": {\n              \"NumPos\": 1260,\n              \"NumEnd\": 1262,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 1275,\n          \"ColumnEnd\": 1302,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f186\",\n              \"QuoteType\": 3,\n              \"NamePos\": 1275,\n              \"NameEnd\": 1279\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1281,\n              \"NameEnd\": 1287\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 1288,\n            \"RightParenPos\": 1302,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1294,\n              \"NameEnd\": 1298\n            },\n            \"Level\": {\n              \"NumPos\": 1298,\n              \"NumEnd\": 1300,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 1313,\n          \"ColumnEnd\": 1340,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f187\",\n              \"QuoteType\": 3,\n              \"NamePos\": 1313,\n              \"NameEnd\": 1317\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1319,\n              \"NameEnd\": 1325\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": {\n            \"CodecPos\": 1326,\n            \"RightParenPos\": 1340,\n            \"Type\": null,\n            \"TypeLevel\": null,\n            \"Name\": {\n              \"Name\": \"ZSTD\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1332,\n              \"NameEnd\": 1336\n            },\n            \"Level\": {\n              \"NumPos\": 1336,\n              \"NumEnd\": 1338,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          },\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 1351,\n          \"ColumnEnd\": 1378,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"f188\",\n              \"QuoteType\": 3,\n              \"NamePos\": 1351,\n              \"NameEnd\": 1355\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DATETIME\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1357,\n              \"NameEnd\": 1365\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"Name\": {\n              \"Name\": \"now\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1374,\n              \"NameEnd\": 1377\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1377,\n              \"RightParenPos\": 1378,\n              \"Items\": {\n                \"ListPos\": 1378,\n                \"ListEnd\": 1378,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"IndexPos\": 1389,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1395,\n              \"NameEnd\": 1400\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1401,\n              \"NameEnd\": 1403\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 1422,\n            \"RightParenPos\": 1427,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1409,\n              \"NameEnd\": 1421\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 1422,\n                \"NumEnd\": 1427,\n                \"Literal\": \"0.001\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 1441,\n            \"NumEnd\": 1442,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 1452,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1458,\n              \"NameEnd\": 1464\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1465,\n              \"NameEnd\": 1467\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 1486,\n            \"RightParenPos\": 1491,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1473,\n              \"NameEnd\": 1485\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 1486,\n                \"NumEnd\": 1491,\n                \"Literal\": \"0.001\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 1505,\n            \"NumEnd\": 1506,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 1516,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1522,\n              \"NameEnd\": 1528\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1529,\n              \"NameEnd\": 1531\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"Name\": {\n              \"Name\": \"minmax\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1537,\n              \"NameEnd\": 1543\n            }\n          },\n          \"Granularity\": {\n            \"NumPos\": 1556,\n            \"NumEnd\": 1557,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 1567,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1573,\n              \"NameEnd\": 1579\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1580,\n              \"NameEnd\": 1582\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 1592,\n            \"RightParenPos\": 1593,\n            \"Name\": {\n              \"Name\": \"set\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1588,\n              \"NameEnd\": 1591\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 1592,\n                \"NumEnd\": 1593,\n                \"Literal\": \"0\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 1607,\n            \"NumEnd\": 1608,\n            \"Literal\": \"4\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 1618,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_f4\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1624,\n              \"NameEnd\": 1630\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"mapValues\",\n                \"QuoteType\": 1,\n                \"NamePos\": 1631,\n                \"NameEnd\": 1640\n              },\n              \"Params\": {\n                \"LeftParenPos\": 1640,\n                \"RightParenPos\": 1643,\n                \"Items\": {\n                  \"ListPos\": 1641,\n                  \"ListEnd\": 1643,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"f4\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1641,\n                        \"NameEnd\": 1643\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 1663,\n            \"RightParenPos\": 1667,\n            \"Name\": {\n              \"Name\": \"bloom_filter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1650,\n              \"NameEnd\": 1662\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 1663,\n                \"NumEnd\": 1667,\n                \"Literal\": \"0.01\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 1681,\n            \"NumEnd\": 1682,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"IndexPos\": 1692,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"idx_f5\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1698,\n              \"NameEnd\": 1704\n            },\n            \"DotIdent\": null\n          },\n          \"ColumnExpr\": {\n            \"Expr\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1705,\n              \"NameEnd\": 1709\n            },\n            \"Alias\": null\n          },\n          \"ColumnType\": {\n            \"LeftParenPos\": 1726,\n            \"RightParenPos\": 1736,\n            \"Name\": {\n              \"Name\": \"tokenbf_v1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1715,\n              \"NameEnd\": 1725\n            },\n            \"Params\": [\n              {\n                \"NumPos\": 1726,\n                \"NumEnd\": 1730,\n                \"Literal\": \"4096\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 1732,\n                \"NumEnd\": 1733,\n                \"Literal\": \"3\",\n                \"Base\": 10\n              },\n              {\n                \"NumPos\": 1735,\n                \"NumEnd\": 1736,\n                \"Literal\": \"0\",\n                \"Base\": 10\n              }\n            ]\n          },\n          \"Granularity\": {\n            \"NumPos\": 1750,\n            \"NumEnd\": 1751,\n            \"Literal\": \"4\",\n            \"Base\": 10\n          }\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 1762,\n      \"EngineEnd\": 2003,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": {\n        \"PartitionPos\": 1785,\n        \"Expr\": {\n          \"ListPos\": 1798,\n          \"ListEnd\": 1814,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"toDate\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 1798,\n                  \"NameEnd\": 1804\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 1804,\n                  \"RightParenPos\": 1814,\n                  \"Items\": {\n                    \"ListPos\": 1805,\n                    \"ListEnd\": 1814,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 1805,\n                          \"NameEnd\": 1814\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Alias\": null\n            }\n          ]\n        }\n      },\n      \"SampleBy\": null,\n      \"TTL\": {\n        \"TTLPos\": 1899,\n        \"ListEnd\": 1939,\n        \"Items\": [\n          {\n            \"TTLPos\": 1899,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": {\n                  \"Name\": \"toDate\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 1903,\n                  \"NameEnd\": 1909\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 1909,\n                  \"RightParenPos\": 1919,\n                  \"Items\": {\n                    \"ListPos\": 1910,\n                    \"ListEnd\": 1919,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 1910,\n                          \"NameEnd\": 1919\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"Name\": {\n                  \"Name\": \"toIntervalDay\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 1923,\n                  \"NameEnd\": 1936\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 1936,\n                  \"RightParenPos\": 1939,\n                  \"Items\": {\n                    \"ListPos\": 1937,\n                    \"ListEnd\": 1939,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"NumPos\": 1937,\n                          \"NumEnd\": 1939,\n                          \"Literal\": \"15\",\n                          \"Base\": 10\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Policy\": null\n          }\n        ]\n      },\n      \"Settings\": {\n        \"SettingsPos\": 1945,\n        \"ListEnd\": 2003,\n        \"Items\": [\n          {\n            \"SettingsPos\": 1954,\n            \"Name\": {\n              \"Name\": \"index_granularity\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1954,\n              \"NameEnd\": 1971\n            },\n            \"Expr\": {\n              \"NumPos\": 1974,\n              \"NumEnd\": 1978,\n              \"Literal\": \"8192\",\n              \"Base\": 10\n            }\n          },\n          {\n            \"SettingsPos\": 1980,\n            \"Name\": {\n              \"Name\": \"ttl_only_drop_parts\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1980,\n              \"NameEnd\": 1999\n            },\n            \"Expr\": {\n              \"NumPos\": 2002,\n              \"NumEnd\": 2003,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            }\n          }\n        ]\n      },\n      \"OrderBy\": {\n        \"OrderPos\": 1820,\n        \"ListEnd\": 1893,\n        \"Items\": [\n          {\n            \"OrderPos\": 1820,\n            \"Expr\": {\n              \"LeftParenPos\": 1829,\n              \"RightParenPos\": 1893,\n              \"Items\": {\n                \"ListPos\": 1830,\n                \"ListEnd\": 1892,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"ts_bucket\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1830,\n                      \"NameEnd\": 1839\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"service_name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1841,\n                      \"NameEnd\": 1853\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1855,\n                      \"NameEnd\": 1859\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"toUnixTimestamp64Nano\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 1861,\n                        \"NameEnd\": 1882\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 1882,\n                        \"RightParenPos\": 1892,\n                        \"Items\": {\n                          \"ListPos\": 1883,\n                          \"ListEnd\": 1892,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"Name\": \"timestamp\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 1883,\n                                \"NameEnd\": 1892\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/desc_table_with_table_keyword.sql.golden.json",
    "content": "[\n  {\n    \"DescribePos\": 0,\n    \"StatementEnd\": 18,\n    \"DescribeType\": \"TABLE\",\n    \"Target\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"mytable\",\n        \"QuoteType\": 1,\n        \"NamePos\": 11,\n        \"NameEnd\": 18\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/desc_table_without_table_keyword.sql.golden.json",
    "content": "[\n  {\n    \"DescribePos\": 0,\n    \"StatementEnd\": 12,\n    \"DescribeType\": \"\",\n    \"Target\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"mytable\",\n        \"QuoteType\": 1,\n        \"NamePos\": 5,\n        \"NameEnd\": 12\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/describe_table_with_table_keyword.sql.golden.json",
    "content": "[\n  {\n    \"DescribePos\": 0,\n    \"StatementEnd\": 22,\n    \"DescribeType\": \"TABLE\",\n    \"Target\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"mytable\",\n        \"QuoteType\": 1,\n        \"NamePos\": 15,\n        \"NameEnd\": 22\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/describe_table_without_table_keyword.sql.golden.json",
    "content": "[\n  {\n    \"DescribePos\": 0,\n    \"StatementEnd\": 16,\n    \"DescribeType\": \"\",\n    \"Target\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"mytable\",\n        \"QuoteType\": 1,\n        \"NamePos\": 9,\n        \"NameEnd\": 16\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/drop_database.sql.golden.json",
    "content": "[\n  {\n    \"DropPos\": 0,\n    \"StatementEnd\": 36,\n    \"Name\": {\n      \"Name\": \"datbase_name\",\n      \"QuoteType\": 1,\n      \"NamePos\": 24,\n      \"NameEnd\": 36\n    },\n    \"IfExists\": true,\n    \"OnCluster\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/drop_role.sql.golden.json",
    "content": "[\n  {\n    \"DropPos\": 0,\n    \"Target\": \"ROLE\",\n    \"StatementEnd\": 108,\n    \"Names\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 20,\n          \"NameEnd\": 28\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 30,\n          \"NameEnd\": 38\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r3_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 40,\n          \"NameEnd\": 48\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r4_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 50,\n          \"NameEnd\": 58\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r5_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 60,\n          \"NameEnd\": 68\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r6_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 70,\n          \"NameEnd\": 78\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r7_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 80,\n          \"NameEnd\": 88\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r8_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 90,\n          \"NameEnd\": 98\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"Name\": \"r9_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 100,\n          \"NameEnd\": 108\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"IfExists\": true,\n    \"Modifier\": \"\",\n    \"From\": null\n  },\n  {\n    \"DropPos\": 110,\n    \"Target\": \"ROLE\",\n    \"StatementEnd\": 146,\n    \"Names\": [\n      {\n        \"Name\": {\n          \"Name\": \"r2_01293_renamed\",\n          \"QuoteType\": 1,\n          \"NamePos\": 130,\n          \"NameEnd\": 146\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"IfExists\": true,\n    \"Modifier\": \"\",\n    \"From\": null\n  },\n  {\n    \"DropPos\": 148,\n    \"Target\": \"ROLE\",\n    \"StatementEnd\": 204,\n    \"Names\": [\n      {\n        \"Name\": {\n          \"Name\": \"r1_01293\",\n          \"QuoteType\": 1,\n          \"NamePos\": 168,\n          \"NameEnd\": 176\n        },\n        \"Scope\": {\n          \"LiteralPos\": 178,\n          \"LiteralEnd\": 179,\n          \"Literal\": \"%\"\n        },\n        \"OnCluster\": null\n      },\n      {\n        \"Name\": {\n          \"LiteralPos\": 183,\n          \"LiteralEnd\": 204,\n          \"Literal\": \"r2_01293@%.myhost.com\"\n        },\n        \"Scope\": null,\n        \"OnCluster\": null\n      }\n    ],\n    \"IfExists\": true,\n    \"Modifier\": \"\",\n    \"From\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/drop_table_basic.sql.golden.json",
    "content": "[\n  {\n    \"DropPos\": 0,\n    \"StatementEnd\": 36,\n    \"DropTarget\": \"TABLE\",\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 21,\n        \"NameEnd\": 25\n      },\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 26,\n        \"NameEnd\": 36\n      }\n    },\n    \"IfExists\": true,\n    \"OnCluster\": null,\n    \"IsTemporary\": false,\n    \"Modifier\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/drop_table_with_no_delay.sql.golden.json",
    "content": "[\n  {\n    \"DropPos\": 0,\n    \"StatementEnd\": 74,\n    \"DropTarget\": \"TABLE\",\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 21,\n        \"NameEnd\": 25\n      },\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 26,\n        \"NameEnd\": 36\n      }\n    },\n    \"IfExists\": true,\n    \"OnCluster\": {\n      \"OnPos\": 37,\n      \"Expr\": {\n        \"LiteralPos\": 49,\n        \"LiteralEnd\": 64,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"IsTemporary\": false,\n    \"Modifier\": \"NO DELAY\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/drop_table_with_on_clsuter.sql.golden.json",
    "content": "[\n  {\n    \"DropPos\": 0,\n    \"StatementEnd\": 65,\n    \"DropTarget\": \"TABLE\",\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 21,\n        \"NameEnd\": 25\n      },\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 26,\n        \"NameEnd\": 36\n      }\n    },\n    \"IfExists\": true,\n    \"OnCluster\": {\n      \"OnPos\": 37,\n      \"Expr\": {\n        \"LiteralPos\": 49,\n        \"LiteralEnd\": 64,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"IsTemporary\": false,\n    \"Modifier\": \"\"\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/grant_privilege.sql.golden.json",
    "content": "[\n  {\n    \"GrantPos\": 0,\n    \"StatementEnd\": 37,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 6,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 12,\n          \"RightParenPos\": 16,\n          \"Items\": {\n            \"ListPos\": 13,\n            \"ListEnd\": 16,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 13,\n                  \"NameEnd\": 14\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 15,\n                  \"NameEnd\": 16\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 21,\n        \"NameEnd\": 23\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 24,\n        \"NameEnd\": 29\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"john\",\n        \"QuoteType\": 1,\n        \"NamePos\": 33,\n        \"NameEnd\": 37\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 39,\n    \"StatementEnd\": 113,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 45,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 51,\n          \"RightParenPos\": 55,\n          \"Items\": {\n            \"ListPos\": 52,\n            \"ListEnd\": 55,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 52,\n                  \"NameEnd\": 53\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 54,\n                  \"NameEnd\": 55\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 60,\n        \"NameEnd\": 62\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 63,\n        \"NameEnd\": 68\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"john\",\n        \"QuoteType\": 1,\n        \"NamePos\": 72,\n        \"NameEnd\": 76\n      }\n    ],\n    \"WithOptions\": [\n      \"GRANT\",\n      \"ADMIN\"\n    ]\n  },\n  {\n    \"GrantPos\": 114,\n    \"StatementEnd\": 147,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 120,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 126,\n          \"RightParenPos\": 130,\n          \"Items\": {\n            \"ListPos\": 127,\n            \"ListEnd\": 130,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 127,\n                  \"NameEnd\": 128\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 129,\n                  \"NameEnd\": 130\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 135,\n        \"NameEnd\": 137\n      },\n      \"Table\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 138,\n        \"NameEnd\": 139\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"john\",\n        \"QuoteType\": 1,\n        \"NamePos\": 143,\n        \"NameEnd\": 147\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 149,\n    \"StatementEnd\": 185,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 155,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 161,\n          \"RightParenPos\": 165,\n          \"Items\": {\n            \"ListPos\": 162,\n            \"ListEnd\": 165,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 162,\n                  \"NameEnd\": 163\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 164,\n                  \"NameEnd\": 165\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 170,\n        \"NameEnd\": 171\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 172,\n        \"NameEnd\": 177\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"john\",\n        \"QuoteType\": 1,\n        \"NamePos\": 181,\n        \"NameEnd\": 185\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 187,\n    \"StatementEnd\": 219,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 193,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 199,\n          \"RightParenPos\": 203,\n          \"Items\": {\n            \"ListPos\": 200,\n            \"ListEnd\": 203,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 200,\n                  \"NameEnd\": 201\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 202,\n                  \"NameEnd\": 203\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 208,\n        \"NameEnd\": 209\n      },\n      \"Table\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 210,\n        \"NameEnd\": 211\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"john\",\n        \"QuoteType\": 1,\n        \"NamePos\": 215,\n        \"NameEnd\": 219\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 221,\n    \"StatementEnd\": 265,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 227,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 233,\n          \"RightParenPos\": 237,\n          \"Items\": {\n            \"ListPos\": 234,\n            \"ListEnd\": 237,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 234,\n                  \"NameEnd\": 235\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 236,\n                  \"NameEnd\": 237\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 242,\n        \"NameEnd\": 243\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 244,\n        \"NameEnd\": 249\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"CURRENT_USER\",\n        \"QuoteType\": 1,\n        \"NamePos\": 253,\n        \"NameEnd\": 265\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 267,\n    \"StatementEnd\": 321,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 273,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 279,\n          \"RightParenPos\": 283,\n          \"Items\": {\n            \"ListPos\": 280,\n            \"ListEnd\": 283,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 280,\n                  \"NameEnd\": 281\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 282,\n                  \"NameEnd\": 283\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 288,\n        \"NameEnd\": 289\n      },\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 290,\n        \"NameEnd\": 295\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"CURRENT_USER\",\n        \"QuoteType\": 1,\n        \"NamePos\": 299,\n        \"NameEnd\": 311\n      },\n      {\n        \"Name\": \"john\",\n        \"QuoteType\": 1,\n        \"NamePos\": 312,\n        \"NameEnd\": 316\n      },\n      {\n        \"Name\": \"mary\",\n        \"QuoteType\": 1,\n        \"NamePos\": 317,\n        \"NameEnd\": 321\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 323,\n    \"StatementEnd\": 372,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 329,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"ALL\"\n        ],\n        \"Params\": null\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 336,\n        \"NameEnd\": 337\n      },\n      \"Table\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 338,\n        \"NameEnd\": 339\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"admin_role\",\n        \"QuoteType\": 1,\n        \"NamePos\": 343,\n        \"NameEnd\": 353\n      }\n    ],\n    \"WithOptions\": [\n      \"GRANT\"\n    ]\n  },\n  {\n    \"GrantPos\": 373,\n    \"StatementEnd\": 435,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 379,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": null\n      },\n      {\n        \"PrivilegePos\": 386,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"INSERT\"\n        ],\n        \"Params\": null\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"database\",\n        \"QuoteType\": 1,\n        \"NamePos\": 396,\n        \"NameEnd\": 404\n      },\n      \"Table\": {\n        \"Name\": \"table_1\",\n        \"QuoteType\": 1,\n        \"NamePos\": 405,\n        \"NameEnd\": 412\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"table_1_select_role\",\n        \"QuoteType\": 1,\n        \"NamePos\": 416,\n        \"NameEnd\": 435\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 437,\n    \"StatementEnd\": 508,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 443,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": {\n          \"LeftParenPos\": 449,\n          \"RightParenPos\": 457,\n          \"Items\": {\n            \"ListPos\": 450,\n            \"ListEnd\": 457,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"x\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 450,\n                  \"NameEnd\": 451\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"y\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 453,\n                  \"NameEnd\": 454\n                },\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"z\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 456,\n                  \"NameEnd\": 457\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        }\n      },\n      {\n        \"PrivilegePos\": 459,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"INSERT\"\n        ],\n        \"Params\": null\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"database\",\n        \"QuoteType\": 1,\n        \"NamePos\": 469,\n        \"NameEnd\": 477\n      },\n      \"Table\": {\n        \"Name\": \"table_1\",\n        \"QuoteType\": 1,\n        \"NamePos\": 478,\n        \"NameEnd\": 485\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"table_1_select_role\",\n        \"QuoteType\": 1,\n        \"NamePos\": 489,\n        \"NameEnd\": 508\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 510,\n    \"StatementEnd\": 558,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 516,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"SELECT\"\n        ],\n        \"Params\": null\n      },\n      {\n        \"PrivilegePos\": 524,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"dictGet\"\n        ],\n        \"Params\": null\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 535,\n        \"NameEnd\": 536\n      },\n      \"Table\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 537,\n        \"NameEnd\": 538\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"select_all_role\",\n        \"QuoteType\": 1,\n        \"NamePos\": 543,\n        \"NameEnd\": 558\n      }\n    ],\n    \"WithOptions\": []\n  },\n  {\n    \"GrantPos\": 560,\n    \"StatementEnd\": 605,\n    \"OnCluster\": null,\n    \"Privileges\": [\n      {\n        \"PrivilegePos\": 566,\n        \"PrivilegeEnd\": 0,\n        \"Keywords\": [\n          \"ADMIN\",\n          \"OPTION\"\n        ],\n        \"Params\": null\n      }\n    ],\n    \"On\": {\n      \"Database\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 582,\n        \"NameEnd\": 583\n      },\n      \"Table\": {\n        \"Name\": \"*\",\n        \"QuoteType\": 0,\n        \"NamePos\": 584,\n        \"NameEnd\": 585\n      }\n    },\n    \"To\": [\n      {\n        \"Name\": \"select_all_role\",\n        \"QuoteType\": 1,\n        \"NamePos\": 590,\n        \"NameEnd\": 605\n      }\n    ],\n    \"WithOptions\": []\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/optimize.sql.golden.json",
    "content": "[\n  {\n    \"OptimizePos\": 0,\n    \"StatementEnd\": 32,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 15,\n        \"NameEnd\": 20\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 21,\n      \"By\": null,\n      \"Except\": null\n    }\n  },\n  {\n    \"OptimizePos\": 49,\n    \"StatementEnd\": 85,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 64,\n        \"NameEnd\": 69\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 70,\n      \"By\": {\n        \"ListPos\": 85,\n        \"ListEnd\": 85,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"*\",\n              \"QuoteType\": 0,\n              \"NamePos\": 85,\n              \"NameEnd\": 85\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": null\n    }\n  },\n  {\n    \"OptimizePos\": 131,\n    \"StatementEnd\": 181,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 146,\n        \"NameEnd\": 151\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 152,\n      \"By\": {\n        \"ListPos\": 167,\n        \"ListEnd\": 181,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"colX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 167,\n              \"NameEnd\": 171\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"colY\",\n              \"QuoteType\": 1,\n              \"NamePos\": 172,\n              \"NameEnd\": 176\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"colZ\",\n              \"QuoteType\": 1,\n              \"NamePos\": 177,\n              \"NameEnd\": 181\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": null\n    }\n  },\n  {\n    \"OptimizePos\": 183,\n    \"StatementEnd\": 219,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 198,\n        \"NameEnd\": 203\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 204,\n      \"By\": {\n        \"ListPos\": 219,\n        \"ListEnd\": 219,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"*\",\n              \"QuoteType\": 0,\n              \"NamePos\": 219,\n              \"NameEnd\": 219\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": {\n        \"ListPos\": 228,\n        \"ListEnd\": 232,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"colX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 228,\n              \"NameEnd\": 232\n            },\n            \"Alias\": null\n          }\n        ]\n      }\n    }\n  },\n  {\n    \"OptimizePos\": 234,\n    \"StatementEnd\": 270,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 249,\n        \"NameEnd\": 254\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 255,\n      \"By\": {\n        \"ListPos\": 270,\n        \"ListEnd\": 270,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"*\",\n              \"QuoteType\": 0,\n              \"NamePos\": 270,\n              \"NameEnd\": 270\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": {\n        \"ListPos\": 279,\n        \"ListEnd\": 290,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"LeftParenPos\": 279,\n              \"RightParenPos\": 290,\n              \"Items\": {\n                \"ListPos\": 280,\n                \"ListEnd\": 290,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"colX\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 280,\n                      \"NameEnd\": 284\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"colY\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 286,\n                      \"NameEnd\": 290\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null\n          }\n        ]\n      }\n    }\n  },\n  {\n    \"OptimizePos\": 293,\n    \"StatementEnd\": 362,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 308,\n        \"NameEnd\": 313\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 314,\n      \"By\": {\n        \"ListPos\": 329,\n        \"ListEnd\": 362,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"COLUMNS\",\n                \"QuoteType\": 1,\n                \"NamePos\": 329,\n                \"NameEnd\": 336\n              },\n              \"Params\": {\n                \"LeftParenPos\": 336,\n                \"RightParenPos\": 362,\n                \"Items\": {\n                  \"ListPos\": 338,\n                  \"ListEnd\": 361,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 338,\n                        \"LiteralEnd\": 361,\n                        \"Literal\": \"column-matched-by-regex\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": null\n    }\n  },\n  {\n    \"OptimizePos\": 365,\n    \"StatementEnd\": 434,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 380,\n        \"NameEnd\": 385\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 386,\n      \"By\": {\n        \"ListPos\": 401,\n        \"ListEnd\": 434,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"COLUMNS\",\n                \"QuoteType\": 1,\n                \"NamePos\": 401,\n                \"NameEnd\": 408\n              },\n              \"Params\": {\n                \"LeftParenPos\": 408,\n                \"RightParenPos\": 434,\n                \"Items\": {\n                  \"ListPos\": 410,\n                  \"ListEnd\": 433,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 410,\n                        \"LiteralEnd\": 433,\n                        \"Literal\": \"column-matched-by-regex\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": {\n        \"ListPos\": 443,\n        \"ListEnd\": 447,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"colX\",\n              \"QuoteType\": 1,\n              \"NamePos\": 443,\n              \"NameEnd\": 447\n            },\n            \"Alias\": null\n          }\n        ]\n      }\n    }\n  },\n  {\n    \"OptimizePos\": 449,\n    \"StatementEnd\": 518,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 464,\n        \"NameEnd\": 469\n      }\n    },\n    \"OnCluster\": null,\n    \"Partition\": null,\n    \"HasFinal\": false,\n    \"Deduplicate\": {\n      \"DeduplicatePos\": 470,\n      \"By\": {\n        \"ListPos\": 485,\n        \"ListEnd\": 518,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"COLUMNS\",\n                \"QuoteType\": 1,\n                \"NamePos\": 485,\n                \"NameEnd\": 492\n              },\n              \"Params\": {\n                \"LeftParenPos\": 492,\n                \"RightParenPos\": 518,\n                \"Items\": {\n                  \"ListPos\": 494,\n                  \"ListEnd\": 517,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 494,\n                        \"LiteralEnd\": 517,\n                        \"Literal\": \"column-matched-by-regex\"\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"Except\": {\n        \"ListPos\": 527,\n        \"ListEnd\": 538,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"LeftParenPos\": 527,\n              \"RightParenPos\": 538,\n              \"Items\": {\n                \"ListPos\": 528,\n                \"ListEnd\": 538,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"colX\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 528,\n                      \"NameEnd\": 532\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"colY\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 534,\n                      \"NameEnd\": 538\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null\n          }\n        ]\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/rename.sql.golden.json",
    "content": "[\n  {\n    \"RenamePos\": 16,\n    \"StatementEnd\": 38,\n    \"RenameTarget\": \"TABLE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 29,\n            \"NameEnd\": 31\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 35,\n            \"NameEnd\": 38\n          }\n        }\n      }\n    ],\n    \"OnCluster\": null\n  },\n  {\n    \"RenamePos\": 40,\n    \"StatementEnd\": 90,\n    \"RenameTarget\": \"TABLE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 53,\n            \"NameEnd\": 55\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 59,\n            \"NameEnd\": 62\n          }\n        }\n      }\n    ],\n    \"OnCluster\": {\n      \"OnPos\": 63,\n      \"Expr\": {\n        \"LiteralPos\": 75,\n        \"LiteralEnd\": 90,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  },\n  {\n    \"RenamePos\": 93,\n    \"StatementEnd\": 126,\n    \"RenameTarget\": \"TABLE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 106,\n            \"NameEnd\": 108\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 112,\n            \"NameEnd\": 115\n          }\n        }\n      },\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 117,\n            \"NameEnd\": 119\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t22\",\n            \"QuoteType\": 1,\n            \"NamePos\": 123,\n            \"NameEnd\": 126\n          }\n        }\n      }\n    ],\n    \"OnCluster\": null\n  },\n  {\n    \"RenamePos\": 128,\n    \"StatementEnd\": 189,\n    \"RenameTarget\": \"TABLE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 141,\n            \"NameEnd\": 143\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 147,\n            \"NameEnd\": 150\n          }\n        }\n      },\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 152,\n            \"NameEnd\": 154\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t22\",\n            \"QuoteType\": 1,\n            \"NamePos\": 158,\n            \"NameEnd\": 161\n          }\n        }\n      }\n    ],\n    \"OnCluster\": {\n      \"OnPos\": 162,\n      \"Expr\": {\n        \"LiteralPos\": 174,\n        \"LiteralEnd\": 189,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  },\n  {\n    \"RenamePos\": 216,\n    \"StatementEnd\": 243,\n    \"RenameTarget\": \"DICTIONARY\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 234,\n            \"NameEnd\": 236\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 240,\n            \"NameEnd\": 243\n          }\n        }\n      }\n    ],\n    \"OnCluster\": null\n  },\n  {\n    \"RenamePos\": 245,\n    \"StatementEnd\": 300,\n    \"RenameTarget\": \"DICTIONARY\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 263,\n            \"NameEnd\": 265\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 269,\n            \"NameEnd\": 272\n          }\n        }\n      }\n    ],\n    \"OnCluster\": {\n      \"OnPos\": 273,\n      \"Expr\": {\n        \"LiteralPos\": 285,\n        \"LiteralEnd\": 300,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  },\n  {\n    \"RenamePos\": 303,\n    \"StatementEnd\": 341,\n    \"RenameTarget\": \"DICTIONARY\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 321,\n            \"NameEnd\": 323\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 327,\n            \"NameEnd\": 330\n          }\n        }\n      },\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 332,\n            \"NameEnd\": 334\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t22\",\n            \"QuoteType\": 1,\n            \"NamePos\": 338,\n            \"NameEnd\": 341\n          }\n        }\n      }\n    ],\n    \"OnCluster\": null\n  },\n  {\n    \"RenamePos\": 343,\n    \"StatementEnd\": 409,\n    \"RenameTarget\": \"DICTIONARY\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 361,\n            \"NameEnd\": 363\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 367,\n            \"NameEnd\": 370\n          }\n        }\n      },\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 372,\n            \"NameEnd\": 374\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t22\",\n            \"QuoteType\": 1,\n            \"NamePos\": 378,\n            \"NameEnd\": 381\n          }\n        }\n      }\n    ],\n    \"OnCluster\": {\n      \"OnPos\": 382,\n      \"Expr\": {\n        \"LiteralPos\": 394,\n        \"LiteralEnd\": 409,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  },\n  {\n    \"RenamePos\": 431,\n    \"StatementEnd\": 456,\n    \"RenameTarget\": \"DATABASE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 447,\n            \"NameEnd\": 449\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 453,\n            \"NameEnd\": 456\n          }\n        }\n      }\n    ],\n    \"OnCluster\": null\n  },\n  {\n    \"RenamePos\": 458,\n    \"StatementEnd\": 511,\n    \"RenameTarget\": \"DATABASE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 474,\n            \"NameEnd\": 476\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 480,\n            \"NameEnd\": 483\n          }\n        }\n      }\n    ],\n    \"OnCluster\": {\n      \"OnPos\": 484,\n      \"Expr\": {\n        \"LiteralPos\": 496,\n        \"LiteralEnd\": 511,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  },\n  {\n    \"RenamePos\": 514,\n    \"StatementEnd\": 550,\n    \"RenameTarget\": \"DATABASE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 530,\n            \"NameEnd\": 532\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 536,\n            \"NameEnd\": 539\n          }\n        }\n      },\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 541,\n            \"NameEnd\": 543\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t22\",\n            \"QuoteType\": 1,\n            \"NamePos\": 547,\n            \"NameEnd\": 550\n          }\n        }\n      }\n    ],\n    \"OnCluster\": null\n  },\n  {\n    \"RenamePos\": 552,\n    \"StatementEnd\": 616,\n    \"RenameTarget\": \"DATABASE\",\n    \"TargetPairList\": [\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 568,\n            \"NameEnd\": 570\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t11\",\n            \"QuoteType\": 1,\n            \"NamePos\": 574,\n            \"NameEnd\": 577\n          }\n        }\n      },\n      {\n        \"Old\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 579,\n            \"NameEnd\": 581\n          }\n        },\n        \"New\": {\n          \"Database\": null,\n          \"Table\": {\n            \"Name\": \"t22\",\n            \"QuoteType\": 1,\n            \"NamePos\": 585,\n            \"NameEnd\": 588\n          }\n        }\n      }\n    ],\n    \"OnCluster\": {\n      \"OnPos\": 589,\n      \"Expr\": {\n        \"LiteralPos\": 601,\n        \"LiteralEnd\": 616,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_create_table.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 26,\n    \"ShowType\": \"CREATE TABLE\",\n    \"Target\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"mytable\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 25\n      }\n    },\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 15,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_comprehensive.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 81,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"LIKE\",\n    \"LikePattern\": {\n      \"LiteralPos\": 21,\n      \"LiteralEnd\": 26,\n      \"Literal\": \"prod%\"\n    },\n    \"Limit\": {\n      \"NumPos\": 34,\n      \"NumEnd\": 35,\n      \"Literal\": \"5\",\n      \"Base\": 10\n    },\n    \"OutFile\": {\n      \"LiteralPos\": 50,\n      \"LiteralEnd\": 67,\n      \"Literal\": \"/tmp/prod_dbs.txt\"\n    },\n    \"Format\": {\n      \"LiteralPos\": 76,\n      \"LiteralEnd\": 80,\n      \"Literal\": \"JSON\"\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_format.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 27,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": {\n      \"LiteralPos\": 22,\n      \"LiteralEnd\": 26,\n      \"Literal\": \"JSON\"\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_format_string.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 37,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": {\n      \"LiteralPos\": 23,\n      \"LiteralEnd\": 35,\n      \"Literal\": \"TabSeparated\"\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_ilike.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 29,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"ILIKE\",\n    \"LikePattern\": {\n      \"LiteralPos\": 22,\n      \"LiteralEnd\": 27,\n      \"Literal\": \"Test%\"\n    },\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_like.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 28,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"LIKE\",\n    \"LikePattern\": {\n      \"LiteralPos\": 21,\n      \"LiteralEnd\": 26,\n      \"Literal\": \"test%\"\n    },\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_limit.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 24,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": {\n      \"NumPos\": 21,\n      \"NumEnd\": 23,\n      \"Literal\": \"10\",\n      \"Base\": 10\n    },\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_not_ilike.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 33,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": true,\n    \"LikeType\": \"ILIKE\",\n    \"LikePattern\": {\n      \"LiteralPos\": 26,\n      \"LiteralEnd\": 31,\n      \"Literal\": \"Temp%\"\n    },\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_not_like.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 32,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": true,\n    \"LikeType\": \"LIKE\",\n    \"LikePattern\": {\n      \"LiteralPos\": 25,\n      \"LiteralEnd\": 30,\n      \"Literal\": \"temp%\"\n    },\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_databases_outfile.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 49,\n    \"ShowType\": \"DATABASES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": null,\n    \"OutFile\": {\n      \"LiteralPos\": 29,\n      \"LiteralEnd\": 47,\n      \"Literal\": \"/tmp/databases.txt\"\n    },\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/show_tables.sql.golden.json",
    "content": "[\n  {\n    \"ShowPos\": 0,\n    \"StatementEnd\": 12,\n    \"ShowType\": \"TABLES\",\n    \"Target\": null,\n    \"NotLike\": false,\n    \"LikeType\": \"\",\n    \"LikePattern\": null,\n    \"Limit\": null,\n    \"OutFile\": null,\n    \"Format\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/systems.sql.golden.json",
    "content": "[\n  {\n    \"SystemPos\": 0,\n    \"Expr\": {\n      \"FlushPos\": 7,\n      \"StatementEnd\": 17,\n      \"Logs\": true,\n      \"Distributed\": null\n    }\n  },\n  {\n    \"SystemPos\": 19,\n    \"Expr\": {\n      \"DropPos\": 26,\n      \"StatementEnd\": 49,\n      \"Type\": \"UNCOMPRESSED CACHE\"\n    }\n  },\n  {\n    \"SystemPos\": 51,\n    \"Expr\": {\n      \"DropPos\": 58,\n      \"StatementEnd\": 79,\n      \"Type\": \"FILESYSTEM CACHE\"\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/truncate_table_basic.sql.golden.json",
    "content": "[\n  {\n    \"TruncatePos\": 0,\n    \"StatementEnd\": 40,\n    \"IsTemporary\": false,\n    \"IfExists\": true,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 25,\n        \"NameEnd\": 29\n      },\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 30,\n        \"NameEnd\": 40\n      }\n    },\n    \"OnCluster\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/output/truncate_temporary_table_on_clsuter.sql.golden.json",
    "content": "[\n  {\n    \"TruncatePos\": 0,\n    \"StatementEnd\": 78,\n    \"IsTemporary\": true,\n    \"IfExists\": true,\n    \"Name\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 35,\n        \"NameEnd\": 39\n      },\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 40,\n        \"NameEnd\": 50\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 51,\n      \"Expr\": {\n        \"LiteralPos\": 63,\n        \"LiteralEnd\": 78,\n        \"Literal\": \"default_cluster\"\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/ddl/rename.sql",
    "content": "-- rename table\nRENAME TABLE t1 TO t11;\nRENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME TABLE t1 TO t11, t2 TO t22;\nRENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n-- rename dictionary   \nRENAME DICTIONARY t1 TO t11;\nRENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DICTIONARY t1 TO t11, t2 TO t22;\nRENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n-- rename database\nRENAME DATABASE t1 TO t11;\nRENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster';\nRENAME DATABASE t1 TO t11, t2 TO t22;\nRENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/ddl/show_create_table.sql",
    "content": "SHOW CREATE TABLE mytable"
  },
  {
    "path": "parser/testdata/ddl/show_databases.sql",
    "content": "SHOW DATABASES"
  },
  {
    "path": "parser/testdata/ddl/show_databases_comprehensive.sql",
    "content": "SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON"
  },
  {
    "path": "parser/testdata/ddl/show_databases_format.sql",
    "content": "SHOW DATABASES FORMAT JSON"
  },
  {
    "path": "parser/testdata/ddl/show_databases_format_string.sql",
    "content": "SHOW DATABASES FORMAT 'TabSeparated'"
  },
  {
    "path": "parser/testdata/ddl/show_databases_ilike.sql",
    "content": "SHOW DATABASES ILIKE 'Test%'"
  },
  {
    "path": "parser/testdata/ddl/show_databases_like.sql",
    "content": "SHOW DATABASES LIKE 'test%'"
  },
  {
    "path": "parser/testdata/ddl/show_databases_limit.sql",
    "content": "SHOW DATABASES LIMIT 10"
  },
  {
    "path": "parser/testdata/ddl/show_databases_not_ilike.sql",
    "content": "SHOW DATABASES NOT ILIKE 'Temp%'"
  },
  {
    "path": "parser/testdata/ddl/show_databases_not_like.sql",
    "content": "SHOW DATABASES NOT LIKE 'temp%'"
  },
  {
    "path": "parser/testdata/ddl/show_databases_outfile.sql",
    "content": "SHOW DATABASES INTO OUTFILE '/tmp/databases.txt'"
  },
  {
    "path": "parser/testdata/ddl/show_tables.sql",
    "content": "SHOW TABLES"
  },
  {
    "path": "parser/testdata/ddl/systems.sql",
    "content": "SYSTEM FLUSH LOGS;\nSYSTEM DROP UNCOMPRESSED CACHE;\nSYSTEM DROP FILESYSTEM CACHE;\n"
  },
  {
    "path": "parser/testdata/ddl/truncate_table_basic.sql",
    "content": "TRUNCATE TABLE IF EXISTS test.table_name;\n"
  },
  {
    "path": "parser/testdata/ddl/truncate_temporary_table_on_clsuter.sql",
    "content": "TRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster';\n"
  },
  {
    "path": "parser/testdata/dml/alter_table_modify_query.sql",
    "content": "ALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3;"
  },
  {
    "path": "parser/testdata/dml/alter_table_modify_ttl_multiple.sql",
    "content": "ALTER TABLE db.t0 ON CLUSTER default_cluster\nMODIFY TTL\n    toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs',\n    toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY;\n"
  },
  {
    "path": "parser/testdata/dml/alter_table_with_comment.sql",
    "content": "ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String default '' comment 'test' ;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String default '';\n"
  },
  {
    "path": "parser/testdata/dml/alter_table_with_modify_remove_ttl.sql",
    "content": "ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL;"
  },
  {
    "path": "parser/testdata/dml/alter_table_with_modify_ttl.sql",
    "content": "ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR;"
  },
  {
    "path": "parser/testdata/dml/create_column_with_ttl.sql",
    "content": "CREATE TABLE example1 (\n    timestamp DateTime,\n    x UInt32 TTL timestamp + INTERVAL 1 MONTH,\n    y UInt32 TTL timestamp + INTERVAL 1 WEEK\n)\nENGINE = MergeTree\nORDER BY tuple()"
  },
  {
    "path": "parser/testdata/dml/delete_from.sql",
    "content": "DELETE FROM hits WHERE Title LIKE '%hello%';\n"
  },
  {
    "path": "parser/testdata/dml/format/alter_table_modify_query.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3;\n\n-- Format SQL:\nALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3;\n"
  },
  {
    "path": "parser/testdata/dml/format/alter_table_modify_ttl_multiple.sql",
    "content": "-- Origin SQL:\nALTER TABLE db.t0 ON CLUSTER default_cluster\nMODIFY TTL\n    toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs',\n    toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY;\n\n\n-- Format SQL:\nALTER TABLE db.t0 ON CLUSTER default_cluster MODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY;\n"
  },
  {
    "path": "parser/testdata/dml/format/alter_table_with_comment.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String default '' comment 'test' ;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String default '';\n\n\n-- Format SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String DEFAULT '' COMMENT 'test';\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String DEFAULT '';\n"
  },
  {
    "path": "parser/testdata/dml/format/alter_table_with_modify_remove_ttl.sql",
    "content": "-- Origin SQL:\nALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL;\n\n-- Format SQL:\nALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL;\n"
  },
  {
    "path": "parser/testdata/dml/format/alter_table_with_modify_ttl.sql",
    "content": "-- Origin SQL:\nALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR;\n\n-- Format SQL:\nALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR;\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/alter_table_modify_query.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3;\n\n-- Beautify SQL:\nALTER TABLE test.some_mv\nON CLUSTER cluster\nMODIFY QUERY\n  SELECT\n    field1,\n    field2\n  FROM\n    test.some_table\n  WHERE\n    count >= 3;\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/alter_table_modify_ttl_multiple.sql",
    "content": "-- Origin SQL:\nALTER TABLE db.t0 ON CLUSTER default_cluster\nMODIFY TTL\n    toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs',\n    toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY;\n\n\n-- Beautify SQL:\nALTER TABLE db.t0\nON CLUSTER default_cluster\nMODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY;\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/alter_table_with_comment.sql",
    "content": "-- Origin SQL:\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String default '' comment 'test' ;\nALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String default '';\n\n\n-- Beautify SQL:\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD COLUMN a.f1 String DEFAULT '' COMMENT 'test';\nALTER TABLE test.events_local\nON CLUSTER 'default_cluster'\nADD COLUMN hello String DEFAULT '';\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/alter_table_with_modify_remove_ttl.sql",
    "content": "-- Origin SQL:\nALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL;\n\n-- Beautify SQL:\nALTER TABLE infra.flow_processed_emails_local\nON CLUSTER default_cluster\nREMOVE TTL;\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/alter_table_with_modify_ttl.sql",
    "content": "-- Origin SQL:\nALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR;\n\n-- Beautify SQL:\nALTER TABLE infra.flow_processed_emails_local\nON CLUSTER default_cluster\nMODIFY TTL created_at + INTERVAL 3 YEAR;\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/create_column_with_ttl.sql",
    "content": "-- Origin SQL:\nCREATE TABLE example1 (\n    timestamp DateTime,\n    x UInt32 TTL timestamp + INTERVAL 1 MONTH,\n    y UInt32 TTL timestamp + INTERVAL 1 WEEK\n)\nENGINE = MergeTree\nORDER BY tuple()\n\n-- Beautify SQL:\nCREATE TABLE example1\n(\n  timestamp DateTime,\n  x UInt32 TTL timestamp + INTERVAL 1 MONTH,\n  y UInt32 TTL timestamp + INTERVAL 1 WEEK\n)\nENGINE = MergeTree\nORDER BY\n  tuple();\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/delete_from.sql",
    "content": "-- Origin SQL:\nDELETE FROM hits WHERE Title LIKE '%hello%';\n\n\n-- Beautify SQL:\nDELETE FROM hits WHERE Title LIKE '%hello%';\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/insert_select_without_from.sql",
    "content": "-- Origin SQL:\nINSERT INTO t (c) SELECT 1 WHERE 1 = 1;\n\n\n\n-- Beautify SQL:\nINSERT INTO t\n  (c)\nSELECT\n  1\nWHERE\n  1 = 1;\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/insert_values.sql",
    "content": "-- Origin SQL:\nINSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES\n    (101, 'Hello, ClickHouse!',                                 now(),       -1.0    ),\n    (102, 'Insert a lot of rows per batch',                     yesterday(), 1.41421 ),\n    (102, 'Sort your data based on your commonly-used queries', today(),     2.718   ),\n    (101, 'Granules are the smallest chunks of data read',      now() + 5,   3.14159 )\n\n-- Beautify SQL:\nINSERT INTO helloworld.my_first_table\n  (user_id, message, timestamp, metric)\nVALUES\n  (101, 'Hello, ClickHouse!', now(), -1.0),\n  (102, 'Insert a lot of rows per batch', yesterday(), 1.41421),\n  (102, 'Sort your data based on your commonly-used queries', today(), 2.718),\n  (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159);\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/insert_with_format.sql",
    "content": "-- Origin SQL:\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`;\nINSERT INTO \"db\".\"table_name\" (col1, col2) VALUES (1, 2);\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2);\nINSERT INTO table_name (col1, col2) VALUES (1, 2) FORMAT Native;\n\n-- Beautify SQL:\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`;\nINSERT INTO \"db\".\"table_name\"\n  (col1, col2)\nVALUES\n  (1, 2);\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`\n  (col1, col2);\nINSERT INTO table_name\n  (col1, col2)\nVALUES\n  (1, 2);\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/insert_with_keyword_placeholder.sql",
    "content": "-- Origin SQL:\nINSERT INTO t (c) VALUES ({name :String});\n\n\n\n-- Beautify SQL:\nINSERT INTO t\n  (c)\nVALUES\n  ({name:String});\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/insert_with_placeholder.sql",
    "content": "-- Origin SQL:\nINSERT INTO t0(user_id, message, timestamp, metric) VALUES\n    (?, ?, ?, ?),\n    (?, ?, ?, ?),\n    (?, ?, ?, ?),\n    (?, ?, ?, ?)\n;\n\nINSERT INTO test_with_typed_columns (id, created_at)\nVALUES ({id: Int32}, {created_at: DateTime64(6)});\n\n-- Beautify SQL:\nINSERT INTO t0\n  (user_id, message, timestamp, metric)\nVALUES\n  (?, ?, ?, ?),\n  (?, ?, ?, ?),\n  (?, ?, ?, ?),\n  (?, ?, ?, ?);\nINSERT INTO test_with_typed_columns\n  (id, created_at)\nVALUES\n  ({id:Int32}, {created_at:DateTime64(6)});\n"
  },
  {
    "path": "parser/testdata/dml/format/beautify/insert_with_select.sql",
    "content": "-- Origin SQL:\nINSERT INTO test.visits_null\nSELECT\n    CounterID,\n    StartDate,\n    Sign,\n    UserID\nFROM test.visits;\n\n-- Beautify SQL:\nINSERT INTO test.visits_null\nSELECT\n  CounterID,\n  StartDate,\n  Sign,\n  UserID\nFROM\n  test.visits;\n"
  },
  {
    "path": "parser/testdata/dml/format/create_column_with_ttl.sql",
    "content": "-- Origin SQL:\nCREATE TABLE example1 (\n    timestamp DateTime,\n    x UInt32 TTL timestamp + INTERVAL 1 MONTH,\n    y UInt32 TTL timestamp + INTERVAL 1 WEEK\n)\nENGINE = MergeTree\nORDER BY tuple()\n\n-- Format SQL:\nCREATE TABLE example1 (timestamp DateTime, x UInt32 TTL timestamp + INTERVAL 1 MONTH, y UInt32 TTL timestamp + INTERVAL 1 WEEK) ENGINE = MergeTree ORDER BY tuple();\n"
  },
  {
    "path": "parser/testdata/dml/format/delete_from.sql",
    "content": "-- Origin SQL:\nDELETE FROM hits WHERE Title LIKE '%hello%';\n\n\n-- Format SQL:\nDELETE FROM hits WHERE Title LIKE '%hello%';\n"
  },
  {
    "path": "parser/testdata/dml/format/insert_select_without_from.sql",
    "content": "-- Origin SQL:\nINSERT INTO t (c) SELECT 1 WHERE 1 = 1;\n\n\n\n-- Format SQL:\nINSERT INTO t (c) SELECT 1 WHERE 1 = 1;\n"
  },
  {
    "path": "parser/testdata/dml/format/insert_values.sql",
    "content": "-- Origin SQL:\nINSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES\n    (101, 'Hello, ClickHouse!',                                 now(),       -1.0    ),\n    (102, 'Insert a lot of rows per batch',                     yesterday(), 1.41421 ),\n    (102, 'Sort your data based on your commonly-used queries', today(),     2.718   ),\n    (101, 'Granules are the smallest chunks of data read',      now() + 5,   3.14159 )\n\n-- Format SQL:\nINSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES (101, 'Hello, ClickHouse!', now(), -1.0), (102, 'Insert a lot of rows per batch', yesterday(), 1.41421), (102, 'Sort your data based on your commonly-used queries', today(), 2.718), (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159);\n"
  },
  {
    "path": "parser/testdata/dml/format/insert_with_format.sql",
    "content": "-- Origin SQL:\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`;\nINSERT INTO \"db\".\"table_name\" (col1, col2) VALUES (1, 2);\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2);\nINSERT INTO table_name (col1, col2) VALUES (1, 2) FORMAT Native;\n\n-- Format SQL:\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`;\nINSERT INTO \"db\".\"table_name\" (col1, col2) VALUES (1, 2);\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2);\nINSERT INTO table_name (col1, col2) VALUES (1, 2);\n"
  },
  {
    "path": "parser/testdata/dml/format/insert_with_keyword_placeholder.sql",
    "content": "-- Origin SQL:\nINSERT INTO t (c) VALUES ({name :String});\n\n\n\n-- Format SQL:\nINSERT INTO t (c) VALUES ({name:String});\n"
  },
  {
    "path": "parser/testdata/dml/format/insert_with_placeholder.sql",
    "content": "-- Origin SQL:\nINSERT INTO t0(user_id, message, timestamp, metric) VALUES\n    (?, ?, ?, ?),\n    (?, ?, ?, ?),\n    (?, ?, ?, ?),\n    (?, ?, ?, ?)\n;\n\nINSERT INTO test_with_typed_columns (id, created_at)\nVALUES ({id: Int32}, {created_at: DateTime64(6)});\n\n-- Format SQL:\nINSERT INTO t0 (user_id, message, timestamp, metric) VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?);\nINSERT INTO test_with_typed_columns (id, created_at) VALUES ({id:Int32}, {created_at:DateTime64(6)});\n"
  },
  {
    "path": "parser/testdata/dml/format/insert_with_select.sql",
    "content": "-- Origin SQL:\nINSERT INTO test.visits_null\nSELECT\n    CounterID,\n    StartDate,\n    Sign,\n    UserID\nFROM test.visits;\n\n-- Format SQL:\nINSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits;\n"
  },
  {
    "path": "parser/testdata/dml/insert_select_without_from.sql",
    "content": "INSERT INTO t (c) SELECT 1 WHERE 1 = 1;\n\n"
  },
  {
    "path": "parser/testdata/dml/insert_values.sql",
    "content": "INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES\n    (101, 'Hello, ClickHouse!',                                 now(),       -1.0    ),\n    (102, 'Insert a lot of rows per batch',                     yesterday(), 1.41421 ),\n    (102, 'Sort your data based on your commonly-used queries', today(),     2.718   ),\n    (101, 'Granules are the smallest chunks of data read',      now() + 5,   3.14159 )"
  },
  {
    "path": "parser/testdata/dml/insert_with_format.sql",
    "content": "INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`;\nINSERT INTO \"db\".\"table_name\" (col1, col2) VALUES (1, 2);\nINSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2);\nINSERT INTO table_name (col1, col2) VALUES (1, 2) FORMAT Native;"
  },
  {
    "path": "parser/testdata/dml/insert_with_keyword_placeholder.sql",
    "content": "INSERT INTO t (c) VALUES ({name :String});\n\n"
  },
  {
    "path": "parser/testdata/dml/insert_with_placeholder.sql",
    "content": "INSERT INTO t0(user_id, message, timestamp, metric) VALUES\n    (?, ?, ?, ?),\n    (?, ?, ?, ?),\n    (?, ?, ?, ?),\n    (?, ?, ?, ?)\n;\n\nINSERT INTO test_with_typed_columns (id, created_at)\nVALUES ({id: Int32}, {created_at: DateTime64(6)});"
  },
  {
    "path": "parser/testdata/dml/insert_with_select.sql",
    "content": "INSERT INTO test.visits_null\nSELECT\n    CounterID,\n    StartDate,\n    Sign,\n    UserID\nFROM test.visits;"
  },
  {
    "path": "parser/testdata/dml/output/alter_table_modify_query.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 116,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"some_mv\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 24\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 25,\n      \"Expr\": {\n        \"Name\": \"cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 36,\n        \"NameEnd\": 43\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"ModifyPos\": 44,\n        \"StatementEnd\": 116,\n        \"SelectExpr\": {\n          \"SelectPos\": 57,\n          \"StatementEnd\": 116,\n          \"With\": null,\n          \"Top\": null,\n          \"HasDistinct\": false,\n          \"DistinctOn\": null,\n          \"SelectItems\": [\n            {\n              \"Expr\": {\n                \"Name\": \"field1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 64,\n                \"NameEnd\": 70\n              },\n              \"Modifiers\": [],\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"Name\": \"field2\",\n                \"QuoteType\": 1,\n                \"NamePos\": 72,\n                \"NameEnd\": 78\n              },\n              \"Modifiers\": [],\n              \"Alias\": null\n            }\n          ],\n          \"From\": {\n            \"FromPos\": 79,\n            \"Expr\": {\n              \"Table\": {\n                \"TablePos\": 84,\n                \"TableEnd\": 99,\n                \"Alias\": null,\n                \"Expr\": {\n                  \"Database\": {\n                    \"Name\": \"test\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 84,\n                    \"NameEnd\": 88\n                  },\n                  \"Table\": {\n                    \"Name\": \"some_table\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 89,\n                    \"NameEnd\": 99\n                  }\n                },\n                \"HasFinal\": false\n              },\n              \"StatementEnd\": 99,\n              \"SampleRatio\": null,\n              \"HasFinal\": false\n            }\n          },\n          \"Window\": null,\n          \"Prewhere\": null,\n          \"Where\": {\n            \"WherePos\": 100,\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"count\",\n                \"QuoteType\": 1,\n                \"NamePos\": 106,\n                \"NameEnd\": 111\n              },\n              \"Operation\": \"\\u003e=\",\n              \"RightExpr\": {\n                \"NumPos\": 115,\n                \"NumEnd\": 116,\n                \"Literal\": \"3\",\n                \"Base\": 10\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            }\n          },\n          \"GroupBy\": null,\n          \"WithTotal\": false,\n          \"Having\": null,\n          \"OrderBy\": null,\n          \"LimitBy\": null,\n          \"Limit\": null,\n          \"Settings\": null,\n          \"Format\": null,\n          \"UnionAll\": null,\n          \"UnionDistinct\": null,\n          \"Except\": null\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/alter_table_modify_ttl_multiple.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 184,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      },\n      \"Table\": {\n        \"Name\": \"t0\",\n        \"QuoteType\": 1,\n        \"NamePos\": 15,\n        \"NameEnd\": 17\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 18,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 29,\n        \"NameEnd\": 44\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"ModifyPos\": 45,\n        \"StatementEnd\": 184,\n        \"TTL\": {\n          \"TTLPos\": 52,\n          \"ListEnd\": 184,\n          \"Items\": [\n            {\n              \"TTLPos\": 52,\n              \"Expr\": {\n                \"LeftExpr\": {\n                  \"Name\": {\n                    \"Name\": \"toDateTime\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 60,\n                    \"NameEnd\": 70\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 70,\n                    \"RightParenPos\": 93,\n                    \"Items\": {\n                      \"ListPos\": 71,\n                      \"ListEnd\": 93,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"LeftExpr\": {\n                              \"Name\": \"timestamp\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 71,\n                              \"NameEnd\": 80\n                            },\n                            \"Operation\": \"/\",\n                            \"RightExpr\": {\n                              \"NumPos\": 83,\n                              \"NumEnd\": 93,\n                              \"Literal\": \"1000000000\",\n                              \"Base\": 10\n                            },\n                            \"HasGlobal\": false,\n                            \"HasNot\": false\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Operation\": \"+\",\n                \"RightExpr\": {\n                  \"IntervalPos\": 97,\n                  \"Expr\": {\n                    \"NumPos\": 106,\n                    \"NumEnd\": 108,\n                    \"Literal\": \"30\",\n                    \"Base\": 10\n                  },\n                  \"Unit\": {\n                    \"Name\": \"DAY\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 109,\n                    \"NameEnd\": 112\n                  }\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Policy\": {\n                \"Item\": {\n                  \"RulePos\": 113,\n                  \"ToVolume\": null,\n                  \"ToDisk\": {\n                    \"LiteralPos\": 122,\n                    \"LiteralEnd\": 125,\n                    \"Literal\": \"gcs\"\n                  },\n                  \"Action\": null\n                },\n                \"Where\": null,\n                \"GroupBy\": null\n              }\n            },\n            {\n              \"TTLPos\": 52,\n              \"Expr\": {\n                \"LeftExpr\": {\n                  \"Name\": {\n                    \"Name\": \"toDateTime\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 132,\n                    \"NameEnd\": 142\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 142,\n                    \"RightParenPos\": 165,\n                    \"Items\": {\n                      \"ListPos\": 143,\n                      \"ListEnd\": 165,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"LeftExpr\": {\n                              \"Name\": \"timestamp\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 143,\n                              \"NameEnd\": 152\n                            },\n                            \"Operation\": \"/\",\n                            \"RightExpr\": {\n                              \"NumPos\": 155,\n                              \"NumEnd\": 165,\n                              \"Literal\": \"1000000000\",\n                              \"Base\": 10\n                            },\n                            \"HasGlobal\": false,\n                            \"HasNot\": false\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Operation\": \"+\",\n                \"RightExpr\": {\n                  \"IntervalPos\": 169,\n                  \"Expr\": {\n                    \"NumPos\": 178,\n                    \"NumEnd\": 180,\n                    \"Literal\": \"60\",\n                    \"Base\": 10\n                  },\n                  \"Unit\": {\n                    \"Name\": \"DAY\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 181,\n                    \"NameEnd\": 184\n                  }\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Policy\": null\n            }\n          ]\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/alter_table_with_comment.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 106,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 29\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 30,\n      \"Expr\": {\n        \"LiteralPos\": 42,\n        \"LiteralEnd\": 57,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 59,\n        \"StatementEnd\": 106,\n        \"Column\": {\n          \"NamePos\": 70,\n          \"ColumnEnd\": 106,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"a\",\n              \"QuoteType\": 1,\n              \"NamePos\": 70,\n              \"NameEnd\": 71\n            },\n            \"DotIdent\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 72,\n              \"NameEnd\": 74\n            }\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 75,\n              \"NameEnd\": 81\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"LiteralPos\": 91,\n            \"LiteralEnd\": 91,\n            \"Literal\": \"\"\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": {\n            \"LiteralPos\": 93,\n            \"LiteralEnd\": 106,\n            \"Literal\": \"test\"\n          },\n          \"CompressionCodec\": null\n        },\n        \"IfNotExists\": false,\n        \"After\": null,\n        \"Settings\": null\n      }\n    ]\n  },\n  {\n    \"AlterPos\": 110,\n    \"StatementEnd\": 202,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 122,\n        \"NameEnd\": 126\n      },\n      \"Table\": {\n        \"Name\": \"events_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 127,\n        \"NameEnd\": 139\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 140,\n      \"Expr\": {\n        \"LiteralPos\": 152,\n        \"LiteralEnd\": 167,\n        \"Literal\": \"default_cluster\"\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"AddPos\": 169,\n        \"StatementEnd\": 202,\n        \"Column\": {\n          \"NamePos\": 180,\n          \"ColumnEnd\": 202,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"hello\",\n              \"QuoteType\": 1,\n              \"NamePos\": 180,\n              \"NameEnd\": 185\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 186,\n              \"NameEnd\": 192\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": {\n            \"LiteralPos\": 202,\n            \"LiteralEnd\": 202,\n            \"Literal\": \"\"\n          },\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        \"IfNotExists\": false,\n        \"After\": null,\n        \"Settings\": null\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/alter_table_with_modify_remove_ttl.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 83,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"infra\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \"flow_processed_emails_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 45\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 46,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 57,\n        \"NameEnd\": 72\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"RemovePos\": 73,\n        \"StatementEnd\": 83\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/alter_table_with_modify_ttl.sql.golden.json",
    "content": "[\n  {\n    \"AlterPos\": 0,\n    \"StatementEnd\": 112,\n    \"TableIdentifier\": {\n      \"Database\": {\n        \"Name\": \"infra\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 17\n      },\n      \"Table\": {\n        \"Name\": \"flow_processed_emails_local\",\n        \"QuoteType\": 1,\n        \"NamePos\": 18,\n        \"NameEnd\": 45\n      }\n    },\n    \"OnCluster\": {\n      \"OnPos\": 46,\n      \"Expr\": {\n        \"Name\": \"default_cluster\",\n        \"QuoteType\": 1,\n        \"NamePos\": 57,\n        \"NameEnd\": 72\n      }\n    },\n    \"AlterExprs\": [\n      {\n        \"ModifyPos\": 73,\n        \"StatementEnd\": 112,\n        \"TTL\": {\n          \"TTLPos\": 80,\n          \"ListEnd\": 112,\n          \"Items\": [\n            {\n              \"TTLPos\": 80,\n              \"Expr\": {\n                \"LeftExpr\": {\n                  \"Name\": \"created_at\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 84,\n                  \"NameEnd\": 94\n                },\n                \"Operation\": \"+\",\n                \"RightExpr\": {\n                  \"IntervalPos\": 97,\n                  \"Expr\": {\n                    \"NumPos\": 106,\n                    \"NumEnd\": 107,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  },\n                  \"Unit\": {\n                    \"Name\": \"YEAR\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 108,\n                    \"NameEnd\": 112\n                  }\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Policy\": null\n            }\n          ]\n        }\n      }\n    ]\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/create_column_with_ttl.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 176,\n    \"OrReplace\": false,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"example1\",\n        \"QuoteType\": 1,\n        \"NamePos\": 13,\n        \"NameEnd\": 21\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": {\n      \"SchemaPos\": 22,\n      \"SchemaEnd\": 140,\n      \"Columns\": [\n        {\n          \"NamePos\": 28,\n          \"ColumnEnd\": 46,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"timestamp\",\n              \"QuoteType\": 1,\n              \"NamePos\": 28,\n              \"NameEnd\": 37\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 38,\n              \"NameEnd\": 46\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": null,\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 52,\n          \"ColumnEnd\": 93,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"x\",\n              \"QuoteType\": 1,\n              \"NamePos\": 52,\n              \"NameEnd\": 53\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 54,\n              \"NameEnd\": 60\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": {\n            \"TTLPos\": 61,\n            \"ListEnd\": 93,\n            \"Items\": [\n              {\n                \"TTLPos\": 61,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"Name\": \"timestamp\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 65,\n                    \"NameEnd\": 74\n                  },\n                  \"Operation\": \"+\",\n                  \"RightExpr\": {\n                    \"IntervalPos\": 77,\n                    \"Expr\": {\n                      \"NumPos\": 86,\n                      \"NumEnd\": 87,\n                      \"Literal\": \"1\",\n                      \"Base\": 10\n                    },\n                    \"Unit\": {\n                      \"Name\": \"MONTH\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 88,\n                      \"NameEnd\": 93\n                    }\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                },\n                \"Policy\": null\n              }\n            ]\n          },\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        },\n        {\n          \"NamePos\": 99,\n          \"ColumnEnd\": 139,\n          \"Name\": {\n            \"Ident\": {\n              \"Name\": \"y\",\n              \"QuoteType\": 1,\n              \"NamePos\": 99,\n              \"NameEnd\": 100\n            },\n            \"DotIdent\": null\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 101,\n              \"NameEnd\": 107\n            }\n          },\n          \"NotNull\": null,\n          \"Nullable\": null,\n          \"DefaultExpr\": null,\n          \"MaterializedExpr\": null,\n          \"AliasExpr\": null,\n          \"Codec\": null,\n          \"TTL\": {\n            \"TTLPos\": 108,\n            \"ListEnd\": 139,\n            \"Items\": [\n              {\n                \"TTLPos\": 108,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"Name\": \"timestamp\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 112,\n                    \"NameEnd\": 121\n                  },\n                  \"Operation\": \"+\",\n                  \"RightExpr\": {\n                    \"IntervalPos\": 124,\n                    \"Expr\": {\n                      \"NumPos\": 133,\n                      \"NumEnd\": 134,\n                      \"Literal\": \"1\",\n                      \"Base\": 10\n                    },\n                    \"Unit\": {\n                      \"Name\": \"WEEK\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 135,\n                      \"NameEnd\": 139\n                    }\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                },\n                \"Policy\": null\n              }\n            ]\n          },\n          \"Comment\": null,\n          \"CompressionCodec\": null\n        }\n      ],\n      \"AliasTable\": null,\n      \"TableFunction\": null\n    },\n    \"Engine\": {\n      \"EnginePos\": 142,\n      \"EngineEnd\": 176,\n      \"Name\": \"MergeTree\",\n      \"Params\": null,\n      \"PrimaryKey\": null,\n      \"PartitionBy\": null,\n      \"SampleBy\": null,\n      \"TTL\": null,\n      \"Settings\": null,\n      \"OrderBy\": {\n        \"OrderPos\": 161,\n        \"ListEnd\": 176,\n        \"Items\": [\n          {\n            \"OrderPos\": 161,\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"tuple\",\n                \"QuoteType\": 1,\n                \"NamePos\": 170,\n                \"NameEnd\": 175\n              },\n              \"Params\": {\n                \"LeftParenPos\": 175,\n                \"RightParenPos\": 176,\n                \"Items\": {\n                  \"ListPos\": 176,\n                  \"ListEnd\": 176,\n                  \"HasDistinct\": false,\n                  \"Items\": []\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Alias\": null,\n            \"Direction\": \"\",\n            \"Fill\": null\n          }\n        ],\n        \"Interpolate\": null\n      }\n    },\n    \"SubQuery\": null,\n    \"TableFunction\": null,\n    \"HasTemporary\": false,\n    \"Comment\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/delete_from.sql.golden.json",
    "content": "[\n  {\n    \"DeletePos\": 0,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"hits\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      }\n    },\n    \"OnCluster\": null,\n    \"WhereExpr\": {\n      \"LeftExpr\": {\n        \"Name\": \"Title\",\n        \"QuoteType\": 1,\n        \"NamePos\": 23,\n        \"NameEnd\": 28\n      },\n      \"Operation\": \"LIKE\",\n      \"RightExpr\": {\n        \"LiteralPos\": 35,\n        \"LiteralEnd\": 42,\n        \"Literal\": \"%hello%\"\n      },\n      \"HasGlobal\": false,\n      \"HasNot\": false\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/insert_select_without_from.sql.golden.json",
    "content": "[\n  {\n    \"InsertPos\": 0,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 13\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 14,\n      \"RightParenPos\": 16,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"c\",\n            \"QuoteType\": 1,\n            \"NamePos\": 15,\n            \"NameEnd\": 16\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": null,\n    \"SelectExpr\": {\n      \"SelectPos\": 18,\n      \"StatementEnd\": 38,\n      \"With\": null,\n      \"Top\": null,\n      \"HasDistinct\": false,\n      \"DistinctOn\": null,\n      \"SelectItems\": [\n        {\n          \"Expr\": {\n            \"NumPos\": 25,\n            \"NumEnd\": 26,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        }\n      ],\n      \"From\": null,\n      \"Window\": null,\n      \"Prewhere\": null,\n      \"Where\": {\n        \"WherePos\": 27,\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"NumPos\": 33,\n            \"NumEnd\": 34,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"Operation\": \"=\",\n          \"RightExpr\": {\n            \"NumPos\": 37,\n            \"NumEnd\": 38,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        }\n      },\n      \"GroupBy\": null,\n      \"WithTotal\": false,\n      \"Having\": null,\n      \"OrderBy\": null,\n      \"LimitBy\": null,\n      \"Limit\": null,\n      \"Settings\": null,\n      \"Format\": null,\n      \"UnionAll\": null,\n      \"UnionDistinct\": null,\n      \"Except\": null\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/insert_values.sql.golden.json",
    "content": "[\n  {\n    \"InsertPos\": 0,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": {\n        \"Name\": \"helloworld\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 22\n      },\n      \"Table\": {\n        \"Name\": \"my_first_table\",\n        \"QuoteType\": 1,\n        \"NamePos\": 23,\n        \"NameEnd\": 37\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 38,\n      \"RightParenPos\": 74,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"user_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 39,\n            \"NameEnd\": 46\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"message\",\n            \"QuoteType\": 1,\n            \"NamePos\": 48,\n            \"NameEnd\": 55\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"timestamp\",\n            \"QuoteType\": 1,\n            \"NamePos\": 57,\n            \"NameEnd\": 66\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"metric\",\n            \"QuoteType\": 1,\n            \"NamePos\": 68,\n            \"NameEnd\": 74\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": [\n      {\n        \"LeftParenPos\": 87,\n        \"RightParenPos\": 168,\n        \"Values\": [\n          {\n            \"NumPos\": 88,\n            \"NumEnd\": 91,\n            \"Literal\": \"101\",\n            \"Base\": 10\n          },\n          {\n            \"LiteralPos\": 94,\n            \"LiteralEnd\": 112,\n            \"Literal\": \"Hello, ClickHouse!\"\n          },\n          {\n            \"Name\": {\n              \"Name\": \"now\",\n              \"QuoteType\": 1,\n              \"NamePos\": 147,\n              \"NameEnd\": 150\n            },\n            \"Params\": {\n              \"LeftParenPos\": 150,\n              \"RightParenPos\": 151,\n              \"Items\": {\n                \"ListPos\": 151,\n                \"ListEnd\": 151,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          {\n            \"NumPos\": 160,\n            \"NumEnd\": 164,\n            \"Literal\": \"-1.0\",\n            \"Base\": 10\n          }\n        ]\n      },\n      {\n        \"LeftParenPos\": 175,\n        \"RightParenPos\": 256,\n        \"Values\": [\n          {\n            \"NumPos\": 176,\n            \"NumEnd\": 179,\n            \"Literal\": \"102\",\n            \"Base\": 10\n          },\n          {\n            \"LiteralPos\": 182,\n            \"LiteralEnd\": 212,\n            \"Literal\": \"Insert a lot of rows per batch\"\n          },\n          {\n            \"Name\": {\n              \"Name\": \"yesterday\",\n              \"QuoteType\": 1,\n              \"NamePos\": 235,\n              \"NameEnd\": 244\n            },\n            \"Params\": {\n              \"LeftParenPos\": 244,\n              \"RightParenPos\": 245,\n              \"Items\": {\n                \"ListPos\": 245,\n                \"ListEnd\": 245,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          {\n            \"NumPos\": 248,\n            \"NumEnd\": 255,\n            \"Literal\": \"1.41421\",\n            \"Base\": 10\n          }\n        ]\n      },\n      {\n        \"LeftParenPos\": 263,\n        \"RightParenPos\": 344,\n        \"Values\": [\n          {\n            \"NumPos\": 264,\n            \"NumEnd\": 267,\n            \"Literal\": \"102\",\n            \"Base\": 10\n          },\n          {\n            \"LiteralPos\": 270,\n            \"LiteralEnd\": 320,\n            \"Literal\": \"Sort your data based on your commonly-used queries\"\n          },\n          {\n            \"Name\": {\n              \"Name\": \"today\",\n              \"QuoteType\": 1,\n              \"NamePos\": 323,\n              \"NameEnd\": 328\n            },\n            \"Params\": {\n              \"LeftParenPos\": 328,\n              \"RightParenPos\": 329,\n              \"Items\": {\n                \"ListPos\": 329,\n                \"ListEnd\": 329,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          {\n            \"NumPos\": 336,\n            \"NumEnd\": 341,\n            \"Literal\": \"2.718\",\n            \"Base\": 10\n          }\n        ]\n      },\n      {\n        \"LeftParenPos\": 351,\n        \"RightParenPos\": 432,\n        \"Values\": [\n          {\n            \"NumPos\": 352,\n            \"NumEnd\": 355,\n            \"Literal\": \"101\",\n            \"Base\": 10\n          },\n          {\n            \"LiteralPos\": 358,\n            \"LiteralEnd\": 403,\n            \"Literal\": \"Granules are the smallest chunks of data read\"\n          },\n          {\n            \"LeftExpr\": {\n              \"Name\": {\n                \"Name\": \"now\",\n                \"QuoteType\": 1,\n                \"NamePos\": 411,\n                \"NameEnd\": 414\n              },\n              \"Params\": {\n                \"LeftParenPos\": 414,\n                \"RightParenPos\": 415,\n                \"Items\": {\n                  \"ListPos\": 415,\n                  \"ListEnd\": 415,\n                  \"HasDistinct\": false,\n                  \"Items\": []\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Operation\": \"+\",\n            \"RightExpr\": {\n              \"NumPos\": 419,\n              \"NumEnd\": 420,\n              \"Literal\": \"5\",\n              \"Base\": 10\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          {\n            \"NumPos\": 424,\n            \"NumEnd\": 431,\n            \"Literal\": \"3.14159\",\n            \"Base\": 10\n          }\n        ]\n      }\n    ],\n    \"SelectExpr\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/insert_with_format.sql.golden.json",
    "content": "[\n  {\n    \"InsertPos\": 0,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": {\n        \"Name\": \"_test_1345# $.ДБ\",\n        \"QuoteType\": 3,\n        \"NamePos\": 13,\n        \"NameEnd\": 31\n      },\n      \"Table\": {\n        \"Name\": \"2. Таблица №2\",\n        \"QuoteType\": 3,\n        \"NamePos\": 34,\n        \"NameEnd\": 56\n      }\n    },\n    \"ColumnNames\": null,\n    \"Values\": null,\n    \"SelectExpr\": null\n  },\n  {\n    \"InsertPos\": 59,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": {\n        \"Name\": \"db\",\n        \"QuoteType\": 2,\n        \"NamePos\": 72,\n        \"NameEnd\": 74\n      },\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 2,\n        \"NamePos\": 77,\n        \"NameEnd\": 87\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 89,\n      \"RightParenPos\": 100,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"col1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 90,\n            \"NameEnd\": 94\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"col2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 96,\n            \"NameEnd\": 100\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": [\n      {\n        \"LeftParenPos\": 109,\n        \"RightParenPos\": 114,\n        \"Values\": [\n          {\n            \"NumPos\": 110,\n            \"NumEnd\": 111,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          {\n            \"NumPos\": 113,\n            \"NumEnd\": 114,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        ]\n      }\n    ],\n    \"SelectExpr\": null\n  },\n  {\n    \"InsertPos\": 117,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": {\n        \"Name\": \"_test_1345# $.ДБ\",\n        \"QuoteType\": 3,\n        \"NamePos\": 130,\n        \"NameEnd\": 148\n      },\n      \"Table\": {\n        \"Name\": \"2. Таблица №2\",\n        \"QuoteType\": 3,\n        \"NamePos\": 151,\n        \"NameEnd\": 173\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 175,\n      \"RightParenPos\": 186,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"col1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 176,\n            \"NameEnd\": 180\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"col2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 182,\n            \"NameEnd\": 186\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": null,\n    \"SelectExpr\": null\n  },\n  {\n    \"InsertPos\": 189,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"table_name\",\n        \"QuoteType\": 1,\n        \"NamePos\": 201,\n        \"NameEnd\": 211\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 212,\n      \"RightParenPos\": 223,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"col1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 213,\n            \"NameEnd\": 217\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"col2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 219,\n            \"NameEnd\": 223\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": [\n      {\n        \"LeftParenPos\": 232,\n        \"RightParenPos\": 237,\n        \"Values\": [\n          {\n            \"NumPos\": 233,\n            \"NumEnd\": 234,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          {\n            \"NumPos\": 236,\n            \"NumEnd\": 237,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        ]\n      }\n    ],\n    \"SelectExpr\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/insert_with_keyword_placeholder.sql.golden.json",
    "content": "[\n  {\n    \"InsertPos\": 0,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 13\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 14,\n      \"RightParenPos\": 16,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"c\",\n            \"QuoteType\": 1,\n            \"NamePos\": 15,\n            \"NameEnd\": 16\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": [\n      {\n        \"LeftParenPos\": 25,\n        \"RightParenPos\": 40,\n        \"Values\": [\n          {\n            \"LeftBracePos\": 26,\n            \"RightBracePos\": 40,\n            \"Name\": {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 27,\n              \"NameEnd\": 31\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 33,\n                \"NameEnd\": 39\n              }\n            }\n          }\n        ]\n      }\n    ],\n    \"SelectExpr\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/insert_with_placeholder.sql.golden.json",
    "content": "[\n  {\n    \"InsertPos\": 0,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"t0\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 14\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 14,\n      \"RightParenPos\": 50,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"user_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 15,\n            \"NameEnd\": 22\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"message\",\n            \"QuoteType\": 1,\n            \"NamePos\": 24,\n            \"NameEnd\": 31\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"timestamp\",\n            \"QuoteType\": 1,\n            \"NamePos\": 33,\n            \"NameEnd\": 42\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"metric\",\n            \"QuoteType\": 1,\n            \"NamePos\": 44,\n            \"NameEnd\": 50\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": [\n      {\n        \"LeftParenPos\": 63,\n        \"RightParenPos\": 74,\n        \"Values\": [\n          {\n            \"PlaceholderPos\": 64,\n            \"PlaceHolderEnd\": 64,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 67,\n            \"PlaceHolderEnd\": 67,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 70,\n            \"PlaceHolderEnd\": 70,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 73,\n            \"PlaceHolderEnd\": 73,\n            \"Type\": \"?\"\n          }\n        ]\n      },\n      {\n        \"LeftParenPos\": 81,\n        \"RightParenPos\": 92,\n        \"Values\": [\n          {\n            \"PlaceholderPos\": 82,\n            \"PlaceHolderEnd\": 82,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 85,\n            \"PlaceHolderEnd\": 85,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 88,\n            \"PlaceHolderEnd\": 88,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 91,\n            \"PlaceHolderEnd\": 91,\n            \"Type\": \"?\"\n          }\n        ]\n      },\n      {\n        \"LeftParenPos\": 99,\n        \"RightParenPos\": 110,\n        \"Values\": [\n          {\n            \"PlaceholderPos\": 100,\n            \"PlaceHolderEnd\": 100,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 103,\n            \"PlaceHolderEnd\": 103,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 106,\n            \"PlaceHolderEnd\": 106,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 109,\n            \"PlaceHolderEnd\": 109,\n            \"Type\": \"?\"\n          }\n        ]\n      },\n      {\n        \"LeftParenPos\": 117,\n        \"RightParenPos\": 128,\n        \"Values\": [\n          {\n            \"PlaceholderPos\": 118,\n            \"PlaceHolderEnd\": 118,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 121,\n            \"PlaceHolderEnd\": 121,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 124,\n            \"PlaceHolderEnd\": 124,\n            \"Type\": \"?\"\n          },\n          {\n            \"PlaceholderPos\": 127,\n            \"PlaceHolderEnd\": 127,\n            \"Type\": \"?\"\n          }\n        ]\n      }\n    ],\n    \"SelectExpr\": null\n  },\n  {\n    \"InsertPos\": 133,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"test_with_typed_columns\",\n        \"QuoteType\": 1,\n        \"NamePos\": 145,\n        \"NameEnd\": 168\n      }\n    },\n    \"ColumnNames\": {\n      \"LeftParenPos\": 169,\n      \"RightParenPos\": 184,\n      \"ColumnNames\": [\n        {\n          \"Ident\": {\n            \"Name\": \"id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 170,\n            \"NameEnd\": 172\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"created_at\",\n            \"QuoteType\": 1,\n            \"NamePos\": 174,\n            \"NameEnd\": 184\n          },\n          \"DotIdent\": null\n        }\n      ]\n    },\n    \"Values\": [\n      {\n        \"LeftParenPos\": 193,\n        \"RightParenPos\": 234,\n        \"Values\": [\n          {\n            \"LeftBracePos\": 194,\n            \"RightBracePos\": 205,\n            \"Name\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 195,\n              \"NameEnd\": 197\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"Int32\",\n                \"QuoteType\": 1,\n                \"NamePos\": 199,\n                \"NameEnd\": 204\n              }\n            }\n          },\n          {\n            \"LeftBracePos\": 207,\n            \"RightBracePos\": 234,\n            \"Name\": {\n              \"Name\": \"created_at\",\n              \"QuoteType\": 1,\n              \"NamePos\": 208,\n              \"NameEnd\": 218\n            },\n            \"Type\": {\n              \"LeftParenPos\": 231,\n              \"RightParenPos\": 232,\n              \"Name\": {\n                \"Name\": \"DateTime64\",\n                \"QuoteType\": 1,\n                \"NamePos\": 220,\n                \"NameEnd\": 230\n              },\n              \"Params\": [\n                {\n                  \"NumPos\": 231,\n                  \"NumEnd\": 232,\n                  \"Literal\": \"6\",\n                  \"Base\": 10\n                }\n              ]\n            }\n          }\n        ]\n      }\n    ],\n    \"SelectExpr\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/dml/output/insert_with_select.sql.golden.json",
    "content": "[\n  {\n    \"InsertPos\": 0,\n    \"Format\": null,\n    \"HasTableKeyword\": false,\n    \"Table\": {\n      \"Database\": {\n        \"Name\": \"test\",\n        \"QuoteType\": 1,\n        \"NamePos\": 12,\n        \"NameEnd\": 16\n      },\n      \"Table\": {\n        \"Name\": \"visits_null\",\n        \"QuoteType\": 1,\n        \"NamePos\": 17,\n        \"NameEnd\": 28\n      }\n    },\n    \"ColumnNames\": null,\n    \"Values\": null,\n    \"SelectExpr\": {\n      \"SelectPos\": 29,\n      \"StatementEnd\": 103,\n      \"With\": null,\n      \"Top\": null,\n      \"HasDistinct\": false,\n      \"DistinctOn\": null,\n      \"SelectItems\": [\n        {\n          \"Expr\": {\n            \"Name\": \"CounterID\",\n            \"QuoteType\": 1,\n            \"NamePos\": 40,\n            \"NameEnd\": 49\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        },\n        {\n          \"Expr\": {\n            \"Name\": \"StartDate\",\n            \"QuoteType\": 1,\n            \"NamePos\": 55,\n            \"NameEnd\": 64\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        },\n        {\n          \"Expr\": {\n            \"Name\": \"Sign\",\n            \"QuoteType\": 1,\n            \"NamePos\": 70,\n            \"NameEnd\": 74\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        },\n        {\n          \"Expr\": {\n            \"Name\": \"UserID\",\n            \"QuoteType\": 1,\n            \"NamePos\": 80,\n            \"NameEnd\": 86\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        }\n      ],\n      \"From\": {\n        \"FromPos\": 87,\n        \"Expr\": {\n          \"Table\": {\n            \"TablePos\": 92,\n            \"TableEnd\": 103,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": {\n                \"Name\": \"test\",\n                \"QuoteType\": 1,\n                \"NamePos\": 92,\n                \"NameEnd\": 96\n              },\n              \"Table\": {\n                \"Name\": \"visits\",\n                \"QuoteType\": 1,\n                \"NamePos\": 97,\n                \"NameEnd\": 103\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 103,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        }\n      },\n      \"Window\": null,\n      \"Prewhere\": null,\n      \"Where\": null,\n      \"GroupBy\": null,\n      \"WithTotal\": false,\n      \"Having\": null,\n      \"OrderBy\": null,\n      \"LimitBy\": null,\n      \"Limit\": null,\n      \"Settings\": null,\n      \"Format\": null,\n      \"UnionAll\": null,\n      \"UnionDistinct\": null,\n      \"Except\": null\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/query/access_tuple_with_dot.sql",
    "content": "SELECT tuple('a','b','c').3, .1234;\n\nSELECT toTypeName( tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)),\n       (tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)).second,\n       tuple('a','b','c').3,\n       tupleElement(tuple('a','b','c'),1)"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00001_count_hits.sql",
    "content": "SELECT count() FROM test.hits\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00002_count_visits.sql",
    "content": "SELECT sum(Sign) FROM test.visits\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00004_top_counters.sql",
    "content": "SELECT CounterID, count() AS c FROM test.hits GROUP BY CounterID ORDER BY c DESC LIMIT 10;\nSELECT CounterID, count() AS c FROM test.hits GROUP BY CounterID ORDER BY c DESC LIMIT 10 SETTINGS optimize_aggregation_in_order = 1\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00005_filtering.sql",
    "content": "SELECT count() FROM test.hits WHERE AdvEngineID != 0\n\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00006_agregates.sql",
    "content": "SELECT sum(AdvEngineID), count(), avg(ResolutionWidth) FROM test.hits\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00007_uniq.sql",
    "content": "SELECT RegionID, uniq(UserID) AS u FROM test.hits WHERE CounterID = 800784 GROUP BY RegionID ORDER BY u DESC, RegionID LIMIT 10 -- nothing\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00008_uniq.sql",
    "content": "SELECT uniq(UserID), uniqIf(UserID, CounterID = 800784), uniqIf(FUniqID, RegionID = 213) FROM test.hits\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00009_uniq_distributed.sql",
    "content": "-- Tags: distributed\n\n\nSELECT uniq(UserID), uniqIf(UserID, CounterID = 800784), uniqIf(FUniqID, RegionID = 213) FROM remote('127.0.0.{1,2}', test, hits)\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00010_quantiles_segfault.sql",
    "content": "SELECT URL AS `ym:ah:URL`, sum((NOT DontCountHits AND NOT Refresh)), quantilesTimingIf(0.1, 0.5, 0.9)((DOMCompleteTiming + LoadEventEndTiming), DOMCompleteTiming != -1 AND LoadEventEndTiming != -1) as t FROM remote('127.0.0.{1,2}', test, hits) WHERE (CounterID = 800784) AND (((DontCountHits = 0) OR (IsNotBounce = 1)) AND (URL != ''))  GROUP BY `ym:ah:URL` WITH TOTALS   HAVING (sum((NOT DontCountHits AND NOT Refresh)) > 0) AND (count() > 0)  ORDER BY sum((NOT DontCountHits AND NOT Refresh)) DESC, URL  LIMIT 0, 1\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00011_sorting.sql",
    "content": "SELECT EventTime::DateTime('Asia/Dubai') FROM test.hits ORDER BY EventTime DESC LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00012_sorting_distributed.sql",
    "content": "-- Tags: distributed\n\n\nSELECT EventTime::DateTime('Asia/Dubai') FROM remote('127.0.0.{1,2}', test, hits) ORDER BY EventTime DESC LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00013_sorting_of_nested.sql",
    "content": "SELECT ParsedParams.Key1 FROM test.visits FINAL WHERE VisitID != 0 AND notEmpty(ParsedParams.Key1) ORDER BY VisitID LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00014_filtering_arrays.sql",
    "content": "SELECT GeneralInterests FROM test.hits WHERE AdvEngineID != 0 ORDER BY GeneralInterests DESC LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00015_totals_and_no_aggregate_functions.sql",
    "content": "SELECT AdvEngineID FROM test.hits GROUP BY AdvEngineID WITH TOTALS ORDER BY AdvEngineID\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00016_any_if_distributed_cond_always_false.sql",
    "content": "-- Tags: distributed\n\n\nSELECT anyIf(SearchPhrase, CounterID = -1) FROM remote('127.0.0.{1,2}:9000', test, hits)\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00017_aggregation_uninitialized_memory.sql",
    "content": "SELECT DISTINCT (URLHierarchy(URL)[1]) AS q, 'x' AS w FROM test.hits WHERE CounterID = 14917930 ORDER BY URL\n\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00020_distinct_order_by_distributed.sql",
    "content": "-- Tags: distributed\n\nSET max_rows_to_sort = 10000;\nSELECT count() FROM (SELECT DISTINCT PredLastVisit AS x FROM remote('127.0.0.{1,2}', test, visits) ORDER BY VisitID);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00021_1_select_with_in.sql",
    "content": "select sum(Sign) from test.visits where CounterID in (942285);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00021_2_select_with_in.sql",
    "content": "select sum(Sign) from test.visits where CounterID in (942285, 577322);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00021_3_select_with_in.sql",
    "content": "select 1 IN (1, 2, 3);\n\nSELECT count() FROM remote('localhost', test, hits) WHERE CounterID IN (598875);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00022_merge_prewhere.sql",
    "content": "DROP TABLE IF EXISTS test.merge_hits;\nCREATE TABLE IF NOT EXISTS test.merge_hits AS test.hits ENGINE = Merge(test, '^hits$');\nSELECT count() FROM test.merge_hits WHERE AdvEngineID = 2;\nSELECT count() FROM test.merge_hits PREWHERE AdvEngineID = 2;\nDROP TABLE test.merge_hits;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00023_totals_limit.sql",
    "content": "SET output_format_write_statistics = 0;\nSELECT goals_alias.ID AS `ym:s:goalDimension`, uniqIf(UserID, (UserID != 0) AND (`_uniq_Goals` = 1))  FROM test.visits ARRAY JOIN Goals AS goals_alias,  arrayEnumerateUniq(Goals.ID)   AS `_uniq_Goals`  WHERE (CounterID = 842440) GROUP BY `ym:s:goalDimension` WITH TOTALS ORDER BY `ym:s:goalDimension` LIMIT 0, 1 FORMAT JSONCompact;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00024_random_counters.sql",
    "content": "SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32152608;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9627212;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25152951;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22202319;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13848191;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27855803;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27944638;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16513894;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4314057;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11878090;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23005927;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17205778;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21296650;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12068702;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8446208;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8439835;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30344780;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2881921;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1828473;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27620040;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14960013;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 103918;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9626742;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18370244;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 813903;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22176733;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17175454;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31608140;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11802602;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12577104;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 153437;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32240558;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27444870;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 79306;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15222279;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11782937;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1677;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9527330;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23580782;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33027895;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 199609;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29139484;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1700065;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30212873;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6773723;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21842879;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9460479;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16451704;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 51267;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30489182;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11947625;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18776987;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25762358;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 74905;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 877422;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3465045;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2084559;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13828281;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30299683;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 132115;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10919775;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12329250;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11525543;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32395537;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24537202;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2270964;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8518291;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11897183;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23805647;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22652078;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19363661;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32339088;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11394550;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1988179;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2135273;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14500371;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10463153;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18838936;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24492652;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26848923;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12495799;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12028938;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8934725;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18602951;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32404741;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19171705;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9831187;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20047182;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26690858;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 126413;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31244775;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15690176;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28374997;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12717244;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9152092;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5397339;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12452068;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13626118;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 46783;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11484344;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21453219;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7692388;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30879805;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27784549;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 665663;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30535786;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11685143;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13652647;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9880318;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30148588;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32745436;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27390924;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17470663;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 196859;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22123478;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 87021;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25264218;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24125574;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26099981;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1141558;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 220829;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15651875;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 182483;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28430678;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31384642;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1008241;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10462834;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26829659;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29130002;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17891770;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26531140;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15014338;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15375411;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7952204;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 41859;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21651593;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9527676;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 107394;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23409492;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31407407;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29312961;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9705505;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29848510;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10187274;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 112606;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15639744;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4375349;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1423039;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13933371;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20430236;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30679961;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 37094;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23197674;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 994587;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 437496;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3904733;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19200606;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 84668;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28581029;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11074306;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2470089;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12251899;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16996077;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12426411;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1034934;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4721601;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22026000;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21031300;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 559124;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15492463;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21419604;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25632271;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14446476;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12684903;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23292922;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26976782;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20269131;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18309978;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5305320;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30926629;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14816057;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19523905;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18775058;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32507411;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25535479;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24858652;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32420158;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4805894;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8157258;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5759745;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12626987;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5342591;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10951832;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9729032;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27999107;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7302193;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30447727;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15764416;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15727130;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15116605;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 527313;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16687935;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28304381;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17699739;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17339596;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29348067;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20861945;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12922065;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27019489;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18299445;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 108465;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 233447;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13042904;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31481509;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2267268;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26140306;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19094364;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25000943;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6860549;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30714288;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16289139;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1419182;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33436573;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30062358;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18167743;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27846382;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30148240;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32332238;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25129158;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14066924;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19832770;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29018190;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 852275;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11328399;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28179212;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20155907;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30685297;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32783957;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1552720;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28110991;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4814424;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20171153;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14920591;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 65690;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14357916;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26533001;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17014738;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11977336;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30142464;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14082365;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18851419;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27638649;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8798932;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 717825;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6912378;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26898048;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5992218;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13422462;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21204372;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17845298;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6933004;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21627605;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3395439;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22315068;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24973444;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27751340;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6022884;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32417601;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18087198;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21940806;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23809389;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9510424;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30651933;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17818815;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9038457;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9153497;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29938964;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10471118;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12913162;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14933629;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7173707;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28680585;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1279785;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33276693;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 573557;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27753414;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22968595;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25211823;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32687774;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6062762;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18866703;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5164840;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6462629;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25039797;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10789598;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33076990;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28960547;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32723171;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17888313;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29810654;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21760643;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16678170;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 368520;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12506284;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9802670;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18488016;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 227003;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15254606;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32580177;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30313645;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20879524;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27222776;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11266528;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17018146;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19902143;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19469853;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22823497;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 56768;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 136798;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16554922;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20627728;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6551053;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 124145;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10881152;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17271030;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28213281;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15665842;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28264219;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29277533;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22926441;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31057728;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8027311;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14229492;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14782220;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29099258;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 99953;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9334015;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16156945;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 124031;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1670442;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21036594;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22954047;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16054043;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 121765;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1482385;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25977258;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24596247;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 550092;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1579438;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1205;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 126296;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 177248;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27523607;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15873699;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11971473;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18965085;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19035683;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29640643;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11929806;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9352219;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18492653;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7967264;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11391453;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4289;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3567;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13575826;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2566437;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21042675;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26498330;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23764459;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32664413;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10116935;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24572551;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26788657;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12830859;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 530033;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6764575;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25219472;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10721285;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26254035;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15486693;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10323514;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23578364;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25449880;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13428298;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17679279;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27610140;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15346859;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 535736;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 513828;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20411888;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13595045;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33221835;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 97601;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12819274;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18047205;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19900235;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27830172;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20839743;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29980468;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27417156;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17908689;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24471592;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32147490;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22966030;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21060870;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 238185;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10152551;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11255139;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 982334;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15199978;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15678357;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18206303;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10902608;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22494906;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22204221;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13097211;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30998656;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26656294;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 922545;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9428510;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15137339;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15578624;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31695129;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15791360;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29571338;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5371768;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15163979;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16312681;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6126176;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16061128;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8528634;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 136544;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3093873;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3994698;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8302978;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16115563;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21804036;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9785708;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10847072;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30692218;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15582824;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19802155;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20835290;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 204284;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25636491;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30446517;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16761451;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 456303;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17301839;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27472581;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24078399;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26345482;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 451381;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8576994;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19418898;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10068353;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3767138;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 758020;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13521375;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25968099;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26805240;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13051011;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 901894;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33097016;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12545080;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29944288;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8250825;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12499373;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22535728;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11929724;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3615273;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24172869;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 116132;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12002817;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23681158;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3938;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8468701;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1295067;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27469232;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32708119;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 122578;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12139400;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12219626;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9262336;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9269892;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 122701;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19589931;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29539889;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31115640;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6283044;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30642040;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18065262;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26714391;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15351586;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13090710;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16201652;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31960256;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2658509;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 467277;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1274110;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23640128;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16197014;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28228612;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11659509;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24981440;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 52285;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30583892;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31467341;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25512316;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2908472;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 422752;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32718035;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14213540;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14951444;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6819113;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9532880;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4102488;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19537427;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7078160;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29521616;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5045377;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23131467;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22383622;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22079706;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29466380;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12045654;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30178011;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20821588;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21966434;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29390311;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19370159;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24857158;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31982180;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11990254;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3841725;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13993951;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31252290;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26398773;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 891512;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27087947;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2097095;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26252354;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13928858;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4331960;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30552074;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27905732;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30049284;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2118697;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20849218;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11338538;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3348692;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17693905;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23502543;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8905975;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18343399;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15235863;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20356153;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10552704;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28875831;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1488561;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15012941;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25726446;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2601050;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27426912;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11269650;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14880200;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 362337;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23533327;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26381021;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17522450;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31868526;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18276314;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1841289;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22234319;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11463222;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15251006;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24841412;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28755796;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9087442;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13734462;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9285105;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13289061;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29890926;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30509694;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17698850;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 46229;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16541087;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11305551;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 429238;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7583796;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8604476;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29759280;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1388922;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10884907;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18220244;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 122157;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18069840;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6707469;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26818794;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14770800;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16652737;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25497243;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14747538;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21371935;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1681601;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5343898;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22040058;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 752596;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9377867;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1848946;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1449313;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31332002;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10829982;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22431161;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29172033;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7631750;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 898844;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21460344;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25387068;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30980374;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13021547;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27715925;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30292547;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18666245;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18954194;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29070192;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 914290;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14807517;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23062682;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5132969;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15094854;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 622095;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1244323;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14804701;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11656845;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17167258;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8959523;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23121135;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4339624;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22679035;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13127067;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18362622;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4189114;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18776826;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26792263;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13409810;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22183039;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16132723;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3925258;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14248840;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18135589;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11234961;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11179577;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 178965;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10138078;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21048048;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8001235;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32833016;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32275374;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1430786;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12969140;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25529912;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18395861;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27380554;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16653574;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16372034;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28050494;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6886254;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7472729;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12646802;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6589761;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19556032;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10261903;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4389;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2415202;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20007939;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17957094;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9920354;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24840314;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5077718;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11650674;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19766470;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7854638;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9169290;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22873394;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30838169;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 79894;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25792494;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25326672;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33123311;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33237554;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15130284;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18811870;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25418177;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17202302;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31836505;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28671820;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25643858;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16338596;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27288074;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9458517;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25163573;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15680967;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20413991;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19332304;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23159444;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24708786;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 250297;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29944728;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14582542;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 512441;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31273184;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30255145;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 89813;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14959234;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26621829;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 279206;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13041403;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33392742;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10895948;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20804625;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10129067;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13855355;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31007051;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4109301;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29492024;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28963180;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11530154;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31889101;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1713672;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16069992;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9075873;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14512529;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8632591;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33056094;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28349520;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26806792;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11496875;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11797321;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25795940;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33196708;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13243216;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25096876;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26974949;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27061789;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29686454;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5045092;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2893170;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21528033;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16980819;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30854698;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1041468;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 215125;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 91347;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22706469;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33038294;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1446406;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 183702;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10246325;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13754526;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6854006;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26686232;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29345198;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15956574;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8558022;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14066782;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31710428;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6750831;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14832055;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29613113;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15159107;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6309003;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4311581;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28180829;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15131841;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20458889;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26250664;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31737265;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 802571;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25064649;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21183784;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3218637;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3375471;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1690000;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18602620;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29918973;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8555235;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32152623;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19670163;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25856874;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6142197;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27822106;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8944163;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7596672;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 129436;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33541084;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5199217;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10337246;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12718765;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10729131;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28049397;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1410155;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24924437;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16706889;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 54647;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29407271;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1575071;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6861225;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30114382;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 129970;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21103497;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3433579;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14174715;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8450741;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30033987;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11474175;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9601520;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7377941;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15646334;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18305797;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2057218;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17121933;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6870927;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19743903;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9019159;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21251610;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 239704;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16170940;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31857931;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25174672;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31546315;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 811438;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33135020;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28325470;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1196502;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 117339;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19198214;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28046111;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27663162;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3651;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8443242;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6773651;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28957858;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15586212;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 155469;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 731800;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13198917;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2080118;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17987407;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1832110;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32960999;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13858070;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2800568;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 381151;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26724412;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 238149;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20458616;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16847984;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14870120;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4729620;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12886810;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 109350;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17512881;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5250020;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 184094;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3071553;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18940958;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16166873;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13648378;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32750584;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31167464;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21597707;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21992900;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16695153;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12272303;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18958518;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11827733;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12495926;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21022681;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32262727;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12082756;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15636497;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20081370;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26349655;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32832383;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18190567;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 61749;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28596915;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28835938;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32924951;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15835912;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22905942;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12295903;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12461093;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27568271;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33525856;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10351138;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16804486;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24506501;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1336365;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19178381;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17921720;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25396786;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22031463;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19624501;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28665905;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14851585;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27554706;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14188052;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33301471;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32896955;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1134828;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27050219;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23641604;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22935857;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29805516;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25890338;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20710225;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3925036;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31404180;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25888177;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11074293;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30922753;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11403908;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25615656;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17652214;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16155802;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5565120;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5508217;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33281735;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11619273;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 67148;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22687534;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17887682;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18506413;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1443226;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13761576;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30941622;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17681363;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 187532;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 95405;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31073741;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9706801;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12504322;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31779591;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18781661;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18284607;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10633383;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3249127;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17567300;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8789986;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30073024;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26477401;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32222832;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23098807;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 50708;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25067039;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29132588;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22947337;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27778601;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25325678;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12822401;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8876685;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31096269;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17466070;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26058342;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1468384;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22665021;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24895973;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15423066;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26091197;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12103346;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15917190;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31527060;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3944;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24572480;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 229185;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17038391;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27368675;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26899897;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13257515;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19531252;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21048946;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33104049;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20824535;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15014380;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25235392;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29560548;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2599836;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32842358;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5795232;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29588193;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19019850;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29580949;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15335748;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15094099;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6308405;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20762370;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14121177;\n\nSYSTEM DROP UNCOMPRESSED CACHE;\n\nSET local_filesystem_read_method = 'pread_threadpool';\nSET min_bytes_to_use_direct_io = 1;\nSET use_uncompressed_cache = 1;\n\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32745436;\nSELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33436573;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00030_array_enumerate_uniq.sql",
    "content": "SELECT max(arrayJoin(arrayEnumerateUniq(arrayMap(x -> intDiv(x, 10), URLCategories)))) FROM test.hits\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00031_array_enumerate_uniq.sql",
    "content": "SELECT UserID, arrayEnumerateUniq(groupArray(SearchPhrase)) AS arr\nFROM\n(\n    SELECT UserID, SearchPhrase\n    FROM test.hits\n    WHERE CounterID = 1704509 AND UserID IN\n    (\n        SELECT UserID\n        FROM test.hits\n        WHERE notEmpty(SearchPhrase) AND CounterID = 1704509\n        GROUP BY UserID\n        HAVING count() > 1\n    )\n    ORDER BY UserID, WatchID\n)\nWHERE notEmpty(SearchPhrase)\nGROUP BY UserID\nHAVING length(arr) > 1\nORDER BY UserID\nLIMIT 20\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00032_aggregate_key64.sql",
    "content": "SELECT SearchEngineID AS k1, count() AS c FROM test.hits GROUP BY k1 ORDER BY c DESC, k1 LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00033_aggregate_key_string.sql",
    "content": "SELECT SearchPhrase AS k1, count() AS c FROM test.hits GROUP BY k1 ORDER BY c DESC, k1 LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00034_aggregate_key_fixed_string.sql",
    "content": "SELECT toFixedString(substring(SearchPhrase, 1, 17), 17) AS k1, count() AS c FROM test.hits GROUP BY k1 ORDER BY c DESC, k1 LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00035_aggregate_keys128.sql",
    "content": "SELECT SearchEngineID AS k1, AdvEngineID AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC, k1, k2 LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00036_aggregate_hashed.sql",
    "content": "SELECT SearchEngineID AS k1, SearchPhrase AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC, k1, k2 LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00037_uniq_state_merge1.sql",
    "content": "SELECT k, any(u) AS u, uniqMerge(us) AS us FROM (SELECT domain(URL) AS k, uniq(UserID) AS u, uniqState(UserID) AS us FROM test.hits GROUP BY k) GROUP BY k ORDER BY u DESC, k ASC LIMIT 100\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00038_uniq_state_merge2.sql",
    "content": "SELECT topLevelDomain(concat('http://', k)) AS tld, sum(u) AS u, uniqMerge(us) AS us FROM (SELECT domain(URL) AS k, uniq(UserID) AS u, uniqState(UserID) AS us FROM test.hits GROUP BY k) GROUP BY tld ORDER BY u DESC, tld ASC LIMIT 100\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00039_primary_key.sql",
    "content": "SELECT count() FROM test.hits WHERE CounterID < 10000;\nSELECT count() FROM test.hits WHERE 10000 > CounterID;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00040_aggregating_materialized_view.sql",
    "content": "DROP TABLE IF EXISTS test.basic_00040;\n\nset allow_deprecated_syntax_for_merge_tree=1;\nCREATE MATERIALIZED VIEW test.basic_00040\nENGINE = AggregatingMergeTree(StartDate, (CounterID, StartDate), 8192)\nPOPULATE AS\nSELECT\n    CounterID,\n    StartDate,\n    sumState(Sign) \t\tAS Visits,\n    uniqState(UserID)\tAS Users\nFROM test.visits\nGROUP BY CounterID, StartDate;\n\n\nSELECT\n    StartDate,\n    sumMerge(Visits)\tAS Visits,\n    uniqMerge(Users)\tAS Users\nFROM test.basic_00040\nGROUP BY StartDate\nORDER BY StartDate;\n\n\nSELECT\n    StartDate,\n    sumMerge(Visits)\tAS Visits,\n    uniqMerge(Users)\tAS Users\nFROM test.basic_00040\nWHERE CounterID = 942285\nGROUP BY StartDate\nORDER BY StartDate;\n\n\nSELECT\n    StartDate,\n    sum(Sign) \t\t\tAS Visits,\n    uniq(UserID)\t\tAS Users\nFROM test.visits\nWHERE CounterID = 942285\nGROUP BY StartDate\nORDER BY StartDate;\n\n\nDROP TABLE test.basic_00040;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00041_aggregating_materialized_view.sql",
    "content": "DROP TABLE IF EXISTS test.basic;\nDROP TABLE IF EXISTS test.visits_null;\n\nCREATE TABLE test.visits_null\n(\n    CounterID UInt32,\n    StartDate Date,\n    Sign Int8,\n    UserID UInt64\n) ENGINE = Null;\n\nset allow_deprecated_syntax_for_merge_tree=1;\nCREATE MATERIALIZED VIEW test.basic\nENGINE = AggregatingMergeTree(StartDate, (CounterID, StartDate), 8192)\nAS SELECT\n    CounterID,\n    StartDate,\n    sumState(Sign)                  AS Visits,\n    uniqState(UserID)               AS Users\nFROM test.visits_null\nGROUP BY CounterID, StartDate;\n\nINSERT INTO test.visits_null\nSELECT\n    CounterID,\n    StartDate,\n    Sign,\n    UserID\nFROM test.visits;\n\n\nSELECT\n    StartDate,\n    sumMerge(Visits)                AS Visits,\n    uniqMerge(Users)                AS Users\nFROM test.basic\nGROUP BY StartDate\nORDER BY StartDate;\n\n\nSELECT\n    StartDate,\n    sumMerge(Visits)                AS Visits,\n    uniqMerge(Users)                AS Users\nFROM test.basic\nWHERE CounterID = 942285\nGROUP BY StartDate\nORDER BY StartDate;\n\n\nSELECT\n    StartDate,\n    sum(Sign)                       AS Visits,\n    uniq(UserID)                    AS Users\nFROM test.visits\nWHERE CounterID = 942285\nGROUP BY StartDate\nORDER BY StartDate;\n\n\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\nOPTIMIZE TABLE test.basic;\n\n\nDROP TABLE test.visits_null;\nDROP TABLE test.basic;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00042_any_left_join.sql",
    "content": "SELECT\n    EventDate,\n    hits,\n    visits\nFROM\n(\n    SELECT\n        EventDate,\n        count() AS hits\n    FROM test.hits\n    GROUP BY EventDate\n) ANY LEFT JOIN\n(\n    SELECT\n        StartDate AS EventDate,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY EventDate\n) USING EventDate\nORDER BY hits DESC\nLIMIT 10\nSETTINGS joined_subquery_requires_alias = 0;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00043_any_left_join.sql",
    "content": "SELECT\n    EventDate,\n    count() AS hits,\n    any(visits)\nFROM test.hits ANY LEFT JOIN\n(\n    SELECT\n        StartDate AS EventDate,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY EventDate\n) USING EventDate\nGROUP BY EventDate\nORDER BY hits DESC\nLIMIT 10\nSETTINGS joined_subquery_requires_alias = 0;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00044_any_left_join_string.sql",
    "content": "SELECT\n    domain,\n    hits,\n    visits\nFROM\n(\n    SELECT\n        domain(URL) AS domain,\n        count() AS hits\n    FROM test.hits\n    GROUP BY domain\n) ANY LEFT JOIN\n(\n    SELECT\n        domain(StartURL) AS domain,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY domain\n) USING domain\nORDER BY hits DESC\nLIMIT 10\nSETTINGS joined_subquery_requires_alias = 0;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00045_uniq_upto.sql",
    "content": "SELECT RegionID, uniqExact(UserID) AS u1, uniqUpTo(10)(UserID) AS u2 FROM test.visits GROUP BY RegionID HAVING u1 <= 11 AND u1 != u2"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00046_uniq_upto_distributed.sql",
    "content": "-- Tags: distributed\n\nSELECT RegionID, uniqExact(UserID) AS u1, uniqUpTo(10)(UserID) AS u2 FROM remote('127.0.0.{1,2}', test, visits) GROUP BY RegionID HAVING u1 <= 11 AND u1 != u2"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00047_bar.sql",
    "content": "SELECT CounterID, count() AS c, bar(c, 0, 523264) FROM test.hits GROUP BY CounterID ORDER BY c DESC, CounterID ASC LIMIT 100;\nSELECT CounterID, count() AS c, bar(c, 0, 523264) FROM test.hits GROUP BY CounterID ORDER BY c DESC, CounterID ASC LIMIT 100 SETTINGS optimize_aggregation_in_order = 1\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00048_min_max.sql",
    "content": "SELECT min(EventDate), max(EventDate) FROM test.hits\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00049_max_string_if.sql",
    "content": "SELECT CounterID, count(), maxIf(SearchPhrase, notEmpty(SearchPhrase)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20;\nSELECT CounterID, count(), maxIf(SearchPhrase, notEmpty(SearchPhrase)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SETTINGS optimize_aggregation_in_order = 1\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00050_min_max.sql",
    "content": "SELECT CounterID, min(WatchID), max(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20;\nSELECT CounterID, min(WatchID), max(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SETTINGS optimize_aggregation_in_order = 1\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00051_min_max_array.sql",
    "content": "SELECT CounterID, count(), max(GoalsReached), min(GoalsReached), minIf(GoalsReached, notEmpty(GoalsReached)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20;\nSELECT CounterID, count(), max(GoalsReached), min(GoalsReached), minIf(GoalsReached, notEmpty(GoalsReached)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SETTINGS optimize_aggregation_in_order = 1\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00052_group_by_in.sql",
    "content": "select StartDate, TraficSourceID in (0) ? 'type_in' : 'other' as traf_type, sum(Sign) \nfrom test.visits \nwhere CounterID = 842440\ngroup by StartDate, traf_type ORDER BY StartDate, traf_type\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00053_replicate_segfault.sql",
    "content": "-- Tags: replica\n\nSELECT count() > 0 FROM (SELECT ParsedParams.Key1 AS p FROM test.visits WHERE arrayAll(y -> arrayExists(x -> y != x, p), p))\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00054_merge_tree_partitions.sql",
    "content": "DROP TABLE IF EXISTS test.partitions;\nset allow_deprecated_syntax_for_merge_tree=1;\nCREATE TABLE test.partitions (EventDate Date, CounterID UInt32) ENGINE = MergeTree(EventDate, CounterID, 8192);\nINSERT INTO test.partitions SELECT EventDate + UserID % 365 AS EventDate, CounterID FROM test.hits WHERE CounterID = 1704509;\n\n\nSELECT count() FROM test.partitions;\nSELECT count() FROM test.partitions WHERE EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01');\nSELECT count() FROM test.partitions WHERE EventDate < toDate('2015-01-01') OR EventDate >= toDate('2015-02-01');\n\nALTER TABLE test.partitions DETACH PARTITION 201501;\n\nSELECT count() FROM test.partitions;\nSELECT count() FROM test.partitions WHERE EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01');\nSELECT count() FROM test.partitions WHERE EventDate < toDate('2015-01-01') OR EventDate >= toDate('2015-02-01');\n\nALTER TABLE test.partitions ATTACH PARTITION 201501;\n\nSELECT count() FROM test.partitions;\nSELECT count() FROM test.partitions WHERE EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01');\nSELECT count() FROM test.partitions WHERE EventDate < toDate('2015-01-01') OR EventDate >= toDate('2015-02-01');\n\n\nALTER TABLE test.partitions DETACH PARTITION 201403;\n\nSELECT count() FROM test.partitions;\n\nINSERT INTO test.partitions SELECT EventDate + UserID % 365 AS EventDate, CounterID FROM test.hits WHERE CounterID = 1704509 AND toStartOfMonth(EventDate) = toDate('2014-03-01');\n\nSELECT count() FROM test.partitions;\n\nALTER TABLE test.partitions ATTACH PARTITION 201403;\n\nSELECT count() FROM test.partitions;\n\n\nDROP TABLE test.partitions;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00055_index_and_not.sql",
    "content": "SELECT count() FROM test.hits WHERE NOT (EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01'))\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00056_view.sql",
    "content": "DROP TABLE IF EXISTS test.view;\nCREATE VIEW test.view AS SELECT CounterID, count() AS c FROM test.hits GROUP BY CounterID;\nSELECT count() FROM test.view;\nSELECT c, count() FROM test.view GROUP BY c ORDER BY count() DESC LIMIT 10;\nSELECT * FROM test.view ORDER BY c DESC LIMIT 10;\nSELECT * FROM test.view SAMPLE 0.1 ORDER BY c DESC LIMIT 10;\nDROP TABLE test.view;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00059_merge_sorting_empty_array_joined.sql",
    "content": "SELECT CounterID FROM test.visits ARRAY JOIN Goals.ID WHERE CounterID = 942285 ORDER BY CounterID\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00060_move_to_prewhere_and_sets.sql",
    "content": "SET optimize_move_to_prewhere = 1;\nSELECT uniq(URL) FROM test.hits WHERE TraficSourceID IN (7);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00061_storage_buffer.sql",
    "content": "DROP TABLE IF EXISTS test.hits_dst;\nDROP TABLE IF EXISTS test.hits_buffer;\n\nCREATE TABLE test.hits_dst AS test.hits;\nCREATE TABLE test.hits_buffer AS test.hits_dst ENGINE = Buffer(test, hits_dst, 8, 1, 10, 10000, 100000, 10000000, 100000000);\n\nINSERT INTO test.hits_buffer SELECT * FROM test.hits WHERE CounterID = 800784;\nSELECT count() FROM test.hits_buffer;\nSELECT count() FROM test.hits_dst;\n\nOPTIMIZE TABLE test.hits_buffer;\nSELECT count() FROM test.hits_buffer;\nSELECT count() FROM test.hits_dst;\n\nDROP TABLE test.hits_dst;\nDROP TABLE test.hits_buffer;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00062_loyalty.sql",
    "content": "SELECT loyalty, count() AS c, bar(log(c + 1) * 1000, 0, log(6000) * 1000, 80) FROM (SELECT UserID, toInt8((yandex > google ? yandex / (yandex + google) : -google / (yandex + google)) * 10) AS loyalty FROM (SELECT UserID, sum(SearchEngineID = 2) AS yandex, sum(SearchEngineID = 3) AS google FROM test.hits WHERE SearchEngineID = 2 OR SearchEngineID = 3 GROUP BY UserID HAVING yandex + google > 10)) GROUP BY loyalty ORDER BY loyalty"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00063_loyalty_joins.sql",
    "content": "SET any_join_distinct_right_table_keys = 1;\nSET joined_subquery_requires_alias = 0;\n\nSELECT\n    loyalty,\n    count()\nFROM test.hits ANY LEFT JOIN\n(\n    SELECT\n        UserID,\n        sum(SearchEngineID = 2) AS yandex,\n        sum(SearchEngineID = 3) AS google,\n        toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty\n    FROM test.hits\n    WHERE (SearchEngineID = 2) OR (SearchEngineID = 3)\n    GROUP BY UserID\n    HAVING (yandex + google) > 10\n) USING UserID\nGROUP BY loyalty\nORDER BY loyalty ASC;\n\n\nSELECT\n    loyalty,\n    count()\nFROM\n(\n    SELECT UserID\n    FROM test.hits\n) ANY LEFT JOIN\n(\n    SELECT\n        UserID,\n        sum(SearchEngineID = 2) AS yandex,\n        sum(SearchEngineID = 3) AS google,\n        toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty\n    FROM test.hits\n    WHERE (SearchEngineID = 2) OR (SearchEngineID = 3)\n    GROUP BY UserID\n    HAVING (yandex + google) > 10\n) USING UserID\nGROUP BY loyalty\nORDER BY loyalty ASC;\n\n\nSELECT\n    loyalty,\n    count()\nFROM\n(\n    SELECT\n        loyalty,\n        UserID\n    FROM\n    (\n        SELECT UserID\n        FROM test.hits\n    ) ANY LEFT JOIN\n    (\n        SELECT\n            UserID,\n            sum(SearchEngineID = 2) AS yandex,\n            sum(SearchEngineID = 3) AS google,\n            toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty\n        FROM test.hits\n        WHERE (SearchEngineID = 2) OR (SearchEngineID = 3)\n        GROUP BY UserID\n        HAVING (yandex + google) > 10\n    ) USING UserID\n)\nGROUP BY loyalty\nORDER BY loyalty ASC;\n\n\nSELECT\n    loyalty,\n    count() AS c,\n    bar(log(c + 1) * 1000, 0, log(3000000) * 1000, 80)\nFROM test.hits ANY INNER JOIN\n(\n    SELECT\n        UserID,\n        toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty\n    FROM\n    (\n        SELECT\n            UserID,\n            sum(SearchEngineID = 2) AS yandex,\n            sum(SearchEngineID = 3) AS google\n        FROM test.hits\n        WHERE (SearchEngineID = 2) OR (SearchEngineID = 3)\n        GROUP BY UserID\n        HAVING (yandex + google) > 10\n    )\n) USING UserID\nGROUP BY loyalty\nORDER BY loyalty ASC;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00065_loyalty_with_storage_join.sql",
    "content": "USE test;\n\nDROP TABLE IF EXISTS join;\nCREATE TABLE join (UserID UInt64, loyalty Int8) ENGINE = Join(SEMI, LEFT, UserID);\n\nINSERT INTO join\nSELECT\n    UserID,\n    toInt8(if((sum(SearchEngineID = 2) AS yandex) > (sum(SearchEngineID = 3) AS google),\n    yandex / (yandex + google),\n    -google / (yandex + google)) * 10) AS loyalty\nFROM hits\nWHERE (SearchEngineID = 2) OR (SearchEngineID = 3)\nGROUP BY UserID\nHAVING (yandex + google) > 10;\n\nSELECT\n    loyalty,\n    count()\nFROM hits SEMI LEFT JOIN join USING UserID\nGROUP BY loyalty\nORDER BY loyalty ASC;\n\nDETACH TABLE join;\nATTACH TABLE join;\n\nSELECT\n    loyalty,\n    count()\nFROM hits SEMI LEFT JOIN join USING UserID\nGROUP BY loyalty\nORDER BY loyalty ASC;\n\nDROP TABLE join;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00066_sorting_distributed_many_replicas.sql",
    "content": "-- Tags: replica, distributed, no-random-settings\n\n\nSET max_parallel_replicas = 2;\nSELECT EventTime::DateTime('Asia/Dubai') FROM remote('127.0.0.{1|2}', test, hits) ORDER BY EventTime DESC LIMIT 10\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00067_union_all.sql",
    "content": "SELECT * FROM\n(\n\tSELECT UserID AS id, 1 AS event\n\tFROM remote('127.0.0.{1,2}', test, hits)\n\tORDER BY id DESC\n\tLIMIT 10\nUNION ALL\n\tSELECT FUniqID AS id, 2 AS event\n\tFROM remote('127.0.0.{1,2}', test, hits)\n\tORDER BY id DESC\n\tLIMIT 10\n)\nORDER BY id, event;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00068_subquery_in_prewhere.sql",
    "content": "SELECT count() FROM test.hits PREWHERE UserID IN (SELECT UserID FROM test.hits WHERE CounterID = 800784);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00069_duplicate_aggregation_keys.sql",
    "content": "SELECT URL, EventDate, max(URL) FROM test.hits WHERE CounterID = 1704509 AND UserID = 4322253409885123546 GROUP BY URL, EventDate, EventDate ORDER BY URL, EventDate;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00071_merge_tree_optimize_aio.sql",
    "content": "DROP TABLE IF EXISTS test.hits_snippet;\n\nset allow_deprecated_syntax_for_merge_tree=1;\nCREATE TABLE test.hits_snippet(EventTime DateTime('Asia/Dubai'),  EventDate Date,  CounterID UInt32,  UserID UInt64,  URL String,  Referer String) ENGINE = MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID), EventTime), 8192);\n\nSET min_insert_block_size_rows = 0, min_insert_block_size_bytes = 0;\nSET max_block_size = 4096;\n\nINSERT INTO test.hits_snippet(EventTime, EventDate, CounterID, UserID, URL, Referer) SELECT EventTime, EventDate, CounterID, UserID, URL, Referer FROM test.hits WHERE EventDate = toDate('2014-03-18') ORDER BY EventTime, EventDate, CounterID, UserID, URL, Referer ASC LIMIT 50;\nINSERT INTO test.hits_snippet(EventTime, EventDate, CounterID, UserID, URL, Referer) SELECT EventTime, EventDate, CounterID, UserID, URL, Referer FROM test.hits WHERE EventDate = toDate('2014-03-19') ORDER BY EventTime, EventDate, CounterID, UserID, URL, Referer ASC LIMIT 50;\n\nSET min_bytes_to_use_direct_io = 8192;\n\nOPTIMIZE TABLE test.hits_snippet;\n\nSELECT EventTime, EventDate, CounterID, UserID, URL, Referer FROM test.hits_snippet ORDER BY EventTime, EventDate, CounterID, UserID, URL, Referer ASC;\n\nDROP TABLE test.hits_snippet;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00072_compare_date_and_string_index.sql",
    "content": "SELECT count() FROM test.hits WHERE EventDate = '2014-03-18';\nSELECT count() FROM test.hits WHERE EventDate < '2014-03-18';\nSELECT count() FROM test.hits WHERE EventDate > '2014-03-18';\nSELECT count() FROM test.hits WHERE EventDate <= '2014-03-18';\nSELECT count() FROM test.hits WHERE EventDate >= '2014-03-18';\nSELECT count() FROM test.hits WHERE EventDate IN ('2014-03-18', '2014-03-19');\n\nSELECT count() FROM test.hits WHERE EventDate = toDate('2014-03-18');\nSELECT count() FROM test.hits WHERE EventDate < toDate('2014-03-18');\nSELECT count() FROM test.hits WHERE EventDate > toDate('2014-03-18');\nSELECT count() FROM test.hits WHERE EventDate <= toDate('2014-03-18');\nSELECT count() FROM test.hits WHERE EventDate >= toDate('2014-03-18');\nSELECT count() FROM test.hits WHERE EventDate IN (toDate('2014-03-18'), toDate('2014-03-19'));\n\nSELECT count() FROM test.hits WHERE EventDate = concat('2014-0', '3-18');\n\nDROP TABLE IF EXISTS test.hits_indexed_by_time;\nCREATE TABLE test.hits_indexed_by_time (EventDate Date, EventTime DateTime('Asia/Dubai')) ENGINE = MergeTree ORDER BY (EventDate, EventTime);\nINSERT INTO test.hits_indexed_by_time SELECT EventDate, EventTime FROM test.hits;\n\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime = '2014-03-18 01:02:03';\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime < '2014-03-18 01:02:03';\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime > '2014-03-18 01:02:03';\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime <= '2014-03-18 01:02:03';\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime >= '2014-03-18 01:02:03';\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime IN ('2014-03-18 01:02:03', '2014-03-19 04:05:06');\n\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime = toDateTime('2014-03-18 01:02:03', 'Asia/Dubai');\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime < toDateTime('2014-03-18 01:02:03', 'Asia/Dubai');\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime > toDateTime('2014-03-18 01:02:03', 'Asia/Dubai');\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime <= toDateTime('2014-03-18 01:02:03', 'Asia/Dubai');\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime >= toDateTime('2014-03-18 01:02:03', 'Asia/Dubai');\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime IN (toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'), toDateTime('2014-03-19 04:05:06', 'Asia/Dubai'));\n\nSELECT count() FROM test.hits_indexed_by_time WHERE EventTime = concat('2014-03-18 ', '01:02:03');\n\nDROP TABLE test.hits_indexed_by_time;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00073_uniq_array.sql",
    "content": "SELECT EventDate, uniqExact(UserID), length(groupUniqArray(UserID)), arrayUniq(groupArray(UserID)) FROM test.hits WHERE CounterID = 1704509 GROUP BY EventDate ORDER BY EventDate;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00074_full_join.sql",
    "content": "set any_join_distinct_right_table_keys = 1;\nset joined_subquery_requires_alias = 0;\n\nSELECT\n    CounterID,\n    hits,\n    visits\nFROM\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        count() AS hits\n    FROM test.hits\n    GROUP BY CounterID\n) ANY FULL OUTER JOIN\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY CounterID\n    HAVING visits > 0\n) USING CounterID\nWHERE hits = 0 OR visits = 0\nORDER BY\n    hits + visits * 10 DESC,\n    CounterID ASC\nLIMIT 20;\n\n\nSELECT\n    CounterID,\n    hits,\n    visits\nFROM\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        count() AS hits\n    FROM test.hits\n    GROUP BY CounterID\n) ANY LEFT JOIN\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY CounterID\n    HAVING visits > 0\n) USING CounterID\nWHERE hits = 0 OR visits = 0\nORDER BY\n    hits + visits * 10 DESC,\n    CounterID ASC\nLIMIT 20;\n\n\nSELECT\n    CounterID,\n    hits,\n    visits\nFROM\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        count() AS hits\n    FROM test.hits\n    GROUP BY CounterID\n) ANY RIGHT JOIN\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY CounterID\n    HAVING visits > 0\n) USING CounterID\nWHERE hits = 0 OR visits = 0\nORDER BY\n    hits + visits * 10 DESC,\n    CounterID ASC\nLIMIT 20;\n\n\nSELECT\n    CounterID,\n    hits,\n    visits\nFROM\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        count() AS hits\n    FROM test.hits\n    GROUP BY CounterID\n) ANY INNER JOIN\n(\n    SELECT\n        (CounterID % 100000) AS CounterID,\n        sum(Sign) AS visits\n    FROM test.visits\n    GROUP BY CounterID\n    HAVING visits > 0\n) USING CounterID\nWHERE hits = 0 OR visits = 0\nORDER BY\n    hits + visits * 10 DESC,\n    CounterID ASC\nLIMIT 20;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00075_left_array_join.sql",
    "content": "SELECT UserID, EventTime::DateTime('Asia/Dubai'), pp.Key1, pp.Key2, ParsedParams.Key1 FROM test.hits ARRAY JOIN ParsedParams AS pp WHERE CounterID = 1704509 ORDER BY UserID, EventTime, pp.Key1, pp.Key2 LIMIT 100;\nSELECT UserID, EventTime::DateTime('Asia/Dubai'), pp.Key1, pp.Key2, ParsedParams.Key1 FROM test.hits LEFT ARRAY JOIN ParsedParams AS pp WHERE CounterID = 1704509 ORDER BY UserID, EventTime, pp.Key1, pp.Key2 LIMIT 100;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00076_system_columns_bytes.sql",
    "content": "-- NOTE: database = currentDatabase() is not mandatory\nSELECT sum(data_compressed_bytes) > 0, sum(data_uncompressed_bytes) > 0, sum(marks_bytes) > 0 FROM system.columns;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00077_log_tinylog_stripelog.sql",
    "content": "SET check_query_single_value_result = 1;\n\nDROP TABLE IF EXISTS test.hits_log;\nDROP TABLE IF EXISTS test.hits_tinylog;\nDROP TABLE IF EXISTS test.hits_stripelog;\n\nCREATE TABLE test.hits_log (CounterID UInt32, AdvEngineID UInt8, RegionID UInt32, SearchPhrase String, UserID UInt64) ENGINE = Log;\nCREATE TABLE test.hits_tinylog (CounterID UInt32, AdvEngineID UInt8, RegionID UInt32, SearchPhrase String, UserID UInt64) ENGINE = TinyLog;\nCREATE TABLE test.hits_stripelog (CounterID UInt32, AdvEngineID UInt8, RegionID UInt32, SearchPhrase String, UserID UInt64) ENGINE = StripeLog;\n\nCHECK TABLE test.hits_log;\nCHECK TABLE test.hits_tinylog;\nCHECK TABLE test.hits_stripelog;\n\nINSERT INTO test.hits_log SELECT CounterID, AdvEngineID, RegionID, SearchPhrase, UserID FROM test.hits;\nINSERT INTO test.hits_tinylog SELECT CounterID, AdvEngineID, RegionID, SearchPhrase, UserID FROM test.hits;\nINSERT INTO test.hits_stripelog SELECT CounterID, AdvEngineID, RegionID, SearchPhrase, UserID FROM test.hits;\n\nSELECT count(), sum(cityHash64(CounterID, AdvEngineID, RegionID, SearchPhrase, UserID)) FROM test.hits;\nSELECT count(), sum(cityHash64(*)) FROM test.hits_log;\nSELECT count(), sum(cityHash64(*)) FROM test.hits_tinylog;\nSELECT count(), sum(cityHash64(*)) FROM test.hits_stripelog;\n\nCHECK TABLE test.hits_log;\nCHECK TABLE test.hits_tinylog;\nCHECK TABLE test.hits_stripelog;\n\nDROP TABLE test.hits_log;\nDROP TABLE test.hits_tinylog;\nDROP TABLE test.hits_stripelog;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00078_group_by_arrays.sql",
    "content": "SELECT GoalsReached AS k, count() AS c FROM test.hits GROUP BY k ORDER BY c DESC LIMIT 10;\nSELECT GeneralInterests AS k1, GoalsReached AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC LIMIT 10;\nSELECT ParsedParams.Key1 AS k1, GeneralInterests AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC LIMIT 10;\nSELECT ParsedParams.Key1 AS k1, GeneralInterests AS k2, count() AS c FROM test.hits WHERE notEmpty(k1) AND notEmpty(k2) GROUP BY k1, k2 ORDER BY c DESC LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00079_array_join_not_used_joined_column.sql",
    "content": "SELECT PP.Key1 AS `ym:s:paramsLevel1`, sum(arrayAll(`x_1` -> `x_1`= '', ParsedParams.Key2)) AS `ym:s:visits` FROM test.hits ARRAY JOIN ParsedParams AS `PP`  WHERE CounterID = 1704509 GROUP BY `ym:s:paramsLevel1` ORDER BY PP.Key1, `ym:s:visits` LIMIT 0, 100;\nSELECT PP.Key1 AS x1, ParsedParams.Key2 AS x2 FROM test.hits ARRAY JOIN ParsedParams AS PP WHERE CounterID = 1704509 ORDER BY x1, x2 LIMIT 10;\nSELECT ParsedParams.Key2 AS x FROM test.hits ARRAY JOIN ParsedParams AS PP ORDER BY x DESC LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00080_array_join_and_union.sql",
    "content": "SELECT count() FROM (SELECT Goals.ID FROM test.visits ARRAY JOIN Goals WHERE CounterID = 842440 LIMIT 10 UNION ALL SELECT Goals.ID FROM test.visits ARRAY JOIN Goals WHERE CounterID = 842440 LIMIT 10);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00081_group_by_without_key_and_totals.sql",
    "content": "SET allow_experimental_analyzer = 1;\n\nSELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'before_having',          max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'after_having_inclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'after_having_exclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'after_having_auto',      max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\n\nSELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'before_having',          max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'after_having_inclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'after_having_exclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'after_having_auto',      max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\n\nSELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'before_having',          max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'after_having_inclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'after_having_exclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\nSELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'after_having_auto',      max_rows_to_group_by = 100000, group_by_overflow_mode = 'any';\n\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00082_quantiles.sql",
    "content": "SELECT CounterID AS k, quantileExact(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\nSELECT CounterID AS k, quantilesExact(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\n\nSELECT CounterID AS k, quantileTiming(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\nSELECT CounterID AS k, quantilesTiming(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\n\n\nSELECT CounterID AS k, quantileExact(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\nSELECT CounterID AS k, quantilesExact(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\n\nSELECT CounterID AS k, quantileTiming(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\nSELECT CounterID AS k, quantilesTiming(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00083_array_filter.sql",
    "content": "SELECT sum(length(ParsedParams.Key1)) FROM test.hits WHERE notEmpty(ParsedParams.Key1);\nSELECT sum(length(ParsedParams.ValueDouble)) FROM test.hits WHERE notEmpty(ParsedParams.ValueDouble);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00084_external_aggregation.sql",
    "content": "SET max_bytes_before_external_group_by = 200000000;\n\nSET max_memory_usage = 1500000000;\nSET max_threads = 12;\nSELECT URL, uniq(SearchPhrase) AS u FROM test.hits GROUP BY URL ORDER BY u DESC, URL LIMIT 10;\n\nSET max_memory_usage = 300000000;\nSET max_threads = 2;\nSET aggregation_memory_efficient_merge_threads = 1;\nSELECT URL, uniq(SearchPhrase) AS u FROM test.hits GROUP BY URL ORDER BY u DESC, URL LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00085_monotonic_evaluation_segfault.sql",
    "content": "SELECT any(0) FROM test.visits WHERE (toInt32(toDateTime(StartDate))) > 1000000000;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00086_array_reduce.sql",
    "content": "SELECT arrayFilter(x -> x != 1, arrayMap((a, b) -> a = b, GeneralInterests, arrayReduce('groupArray', GeneralInterests))) AS res FROM test.hits WHERE length(res) != 0;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00087_where_0.sql",
    "content": "SET max_rows_to_read = 1000;\nSELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 != 0 GROUP BY CounterID;\nSELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 != 0 GROUP BY CounterID SETTINGS optimize_aggregation_in_order = 1;\nSELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 AND CounterID = 1704509 GROUP BY CounterID;\nSELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 AND CounterID = 1704509 GROUP BY CounterID SETTINGS optimize_aggregation_in_order = 1;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00088_global_in_one_shard_and_rows_before_limit.sql",
    "content": "-- Tags: shard\n\nSET output_format_write_statistics = 0;\nSELECT EventDate, count() FROM remote('127.0.0.1', test.hits) WHERE UserID GLOBAL IN (SELECT UserID FROM test.hits) GROUP BY EventDate ORDER BY EventDate LIMIT 5 FORMAT JSONCompact;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00089_position_functions_with_non_constant_arg.sql",
    "content": "SET max_threads = 0; -- let's reset to automatic detection of the number of threads, otherwise test can be slow.\n\nSELECT count() FROM test.hits WHERE position(URL, 'metrika') != position(URL, materialize('metrika'));\nSELECT count() FROM test.hits WHERE positionCaseInsensitive(URL, 'metrika') != positionCaseInsensitive(URL, materialize('metrika'));\nSELECT count() FROM test.hits WHERE positionUTF8(Title, 'новости') != positionUTF8(Title, materialize('новости'));\nSELECT count() FROM test.hits WHERE positionCaseInsensitiveUTF8(Title, 'новости') != positionCaseInsensitiveUTF8(Title, materialize('новости'));\n\nSELECT position(URL, domain(URL)) AS x FROM test.hits WHERE x = 0 AND URL NOT LIKE '%yandex.ru%' LIMIT 100;\nSELECT URL FROM test.hits WHERE x > 10 ORDER BY position(URL, domain(URL)) AS x DESC, URL LIMIT 2;\nSELECT DISTINCT URL, URLDomain, position('http://yandex.ru/', domain(URL)) AS x FROM test.hits WHERE x > 8 ORDER BY position('http://yandex.ru/', domain(URL)) DESC, URL LIMIT 3;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00091_prewhere_two_conditions.sql",
    "content": "-- Tags: no-parallel-replicas\n-- Requires investigation (max_bytes_to_read is not respected)\n\nSET max_bytes_to_read = 600000000;\n\nSET optimize_move_to_prewhere = 1;\n\nSELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00';\nSELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND URL != '' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00';\nSELECT uniq(*) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00' AND EventDate = '2014-03-21';\nWITH toTimeZone(EventTime, 'Asia/Dubai') AS xyz SELECT uniq(*) FROM test.hits WHERE xyz >= '2014-03-20 00:00:00' AND xyz < '2014-03-21 00:00:00' AND EventDate = '2014-03-21';\n\nSET optimize_move_to_prewhere = 0;\n\nSELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00'; -- { serverError 307 }\nSELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND URL != '' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00'; -- { serverError 307 }\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00093_prewhere_array_join.sql",
    "content": "SELECT arrayJoin([SearchEngineID]) AS search_engine, URL FROM test.hits WHERE SearchEngineID != 0 AND search_engine != 0 FORMAT Null;\n\nSELECT\n    arrayJoin([0]) AS browser,\n    arrayJoin([SearchEngineID]) AS search_engine,\n    URL\nFROM test.hits\nWHERE 1 AND (SearchEngineID != 0) AND (browser != 0) AND (search_engine != 0)\nFORMAT Null;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00094_order_by_array_join_limit.sql",
    "content": "SELECT `ParsedParams.Key2` AS x\nFROM test.hits\nARRAY JOIN ParsedParams AS PP\nORDER BY x ASC\nLIMIT 2;\n\nSELECT arrayJoin(`ParsedParams.Key2`) AS x FROM test.hits ORDER BY x ASC LIMIT 2;\nWITH arrayJoin(`ParsedParams.Key2`) AS pp SELECT ParsedParams.Key2 AS x FROM test.hits ORDER BY x ASC LIMIT 2;\nWITH arrayJoin(`ParsedParams.Key2`) AS pp SELECT ParsedParams.Key2 AS x FROM test.hits WHERE NOT ignore(pp) ORDER BY x ASC LIMIT 2;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00095_hyperscan_profiler.sql",
    "content": "-- Tags: no-debug, use-vectorscan\n\n-- Check that server does not get segfault due to bad stack unwinding from Hyperscan\n\nSET query_profiler_cpu_time_period_ns = 1000000;\nSET query_profiler_real_time_period_ns = 1000000;\n\nSELECT count() FROM test.hits WHERE multiFuzzyMatchAny(URL, 2, ['about/address', 'for_woman', '^https?://lm-company.ruy/$', 'ultimateguitar.com']);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00097_constexpr_in_index.sql",
    "content": "-- Even in presense of OR, we evaluate the \"0 IN (1, 2, 3)\" as a constant expression therefore it does not prevent the index analysis.\n\nSELECT count() FROM test.hits WHERE CounterID IN (14917930, 33034174) OR 0 IN (1, 2, 3) SETTINGS max_rows_to_read = 1000000, force_primary_key = 1;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00139_like.sql",
    "content": "/* Note that queries are written as the user doesn't really understand that the symbol _ has special meaning in LIKE pattern. */\nSELECT count() FROM test.hits WHERE URL LIKE '%/avtomobili_s_probegom/_%__%__%__%';\nSELECT count() FROM test.hits WHERE URL LIKE '/avtomobili_s_probegom/_%__%__%__%';\nSELECT count() FROM test.hits WHERE URL LIKE '%_/avtomobili_s_probegom/_%__%__%__%';\nSELECT count() FROM test.hits WHERE URL LIKE '%avtomobili%';\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00140_rename.sql",
    "content": "-- Tags: no-replicated-database, no-parallel\n-- Tag no-replicated-database: Does not support renaming of multiple tables in single query\n\nRENAME TABLE test.hits TO test.visits_tmp, test.visits TO test.hits, test.visits_tmp TO test.visits;\n\nSELECT sum(Sign) FROM test.hits WHERE CounterID = 912887;\nSELECT count() FROM test.visits WHERE CounterID = 732797;\n\nRENAME TABLE test.hits TO test.hits_tmp, test.hits_tmp TO test.hits;\n\nSELECT sum(Sign) FROM test.hits WHERE CounterID = 912887;\nSELECT count() FROM test.visits WHERE CounterID = 732797;\n\nRENAME TABLE test.hits TO test.visits_tmp, test.visits TO test.hits, test.visits_tmp TO test.visits;\n\nSELECT count() FROM test.hits WHERE CounterID = 732797;\nSELECT sum(Sign) FROM test.visits WHERE CounterID = 912887;\n\nRENAME TABLE test.hits TO test.hits2, test.hits2 TO test.hits3, test.hits3 TO test.hits4, test.hits4 TO test.hits5, test.hits5 TO test.hits6, test.hits6 TO test.hits7, test.hits7 TO test.hits8, test.hits8 TO test.hits9, test.hits9 TO test.hits10;\n\nSELECT count() FROM test.hits10 WHERE CounterID = 732797;\n\nRENAME TABLE test.hits10 TO test.hits;\n\nSELECT count() FROM test.hits WHERE CounterID = 732797;\n\nRENAME TABLE test.hits TO default.hits, test.visits TO test.hits;\n\nSELECT sum(Sign) FROM test.hits WHERE CounterID = 912887;\nSELECT count() FROM default.hits WHERE CounterID = 732797;\n\nRENAME TABLE test.hits TO test.visits, default.hits TO test.hits;\n\nSELECT count() FROM test.hits WHERE CounterID = 732797;\nSELECT sum(Sign) FROM test.visits WHERE CounterID = 912887;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00141_transform.sql",
    "content": "SELECT transform(SearchEngineID, [2, 3], ['Яндекс', 'Google'], 'Остальные') AS title, count() AS c FROM test.hits WHERE SearchEngineID != 0 GROUP BY title HAVING c > 0 ORDER BY c DESC LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00142_system_columns.sql",
    "content": "SELECT table, name, type, default_kind, default_expression FROM system.columns WHERE database = 'test' AND table = 'hits'\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00143_transform_non_const_default.sql",
    "content": "SELECT transform(SearchEngineID, [2, 3], ['Яндекс', 'Google'], PageCharset) AS title, count() AS c FROM test.hits WHERE SearchEngineID != 0 GROUP BY title HAVING c > 0 ORDER BY c DESC LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00144_functions_of_aggregation_states.sql",
    "content": "SELECT EventDate, finalizeAggregation(state), runningAccumulate(state) FROM (SELECT EventDate, uniqState(UserID) AS state FROM test.hits GROUP BY EventDate ORDER BY EventDate);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00145_aggregate_functions_statistics.sql",
    "content": "SELECT varSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0);\nSELECT varSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1);\nSELECT round(varSamp(ResolutionWidth), 6) FROM test.hits;\n\nSELECT stddevSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0);\nSELECT stddevSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1);\nSELECT round(stddevSamp(ResolutionWidth), 6) FROM test.hits;\n\nSELECT varPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0);\nSELECT varPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1);\nSELECT round(varPop(ResolutionWidth), 6) FROM test.hits;\n\nSELECT stddevPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0);\nSELECT stddevPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1);\nSELECT round(stddevPop(ResolutionWidth), 6) FROM test.hits;\n\nSELECT covarSamp(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 0);\nSELECT covarSamp(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 1);\nSELECT round(covarSamp(ResolutionWidth, ResolutionHeight), 6) FROM test.hits;\n\nSELECT covarPop(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 0);\nSELECT covarPop(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 1);\nSELECT round(covarPop(ResolutionWidth, ResolutionHeight), 6) FROM test.hits;\n\nSELECT corr(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 0);\nSELECT corr(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 1);\nSELECT round(corr(ResolutionWidth, ResolutionHeight), 6) FROM test.hits;\n\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00146_aggregate_function_uniq.sql",
    "content": "SELECT RegionID, uniqHLL12(WatchID) AS X FROM remote('127.0.0.{1,2}', test, hits) GROUP BY RegionID HAVING X > 100000 ORDER BY RegionID ASC;\nSELECT RegionID, uniqCombined(WatchID) AS X FROM remote('127.0.0.{1,2}', test, hits) GROUP BY RegionID HAVING X > 100000 ORDER BY RegionID ASC;\nSELECT abs(uniq(WatchID) - uniqExact(WatchID)) FROM test.hits;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00147_global_in_aggregate_function.sql",
    "content": "-- Tags: global\n\nSELECT sum(UserID GLOBAL IN (SELECT UserID FROM remote('127.0.0.{1,2}', test.hits))) FROM remote('127.0.0.{1,2}', test.hits);\nSELECT sum(UserID GLOBAL IN (SELECT UserID FROM test.hits)) FROM remote('127.0.0.{1,2}', test.hits);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00148_monotonic_functions_and_index.sql",
    "content": "SET max_rows_to_read = 60000;\n\nSELECT count() FROM test.hits WHERE -CounterID = -1731;\nSELECT count() FROM test.hits WHERE abs(-CounterID) = 1731;\nSELECT count() FROM test.hits WHERE -abs(CounterID) = -1731;\nSELECT count() FROM test.hits WHERE toUInt32(CounterID) = 1731;\nSELECT count() FROM test.hits WHERE toInt32(CounterID) = 1731;\nSELECT count() FROM test.hits WHERE toFloat32(CounterID) = 1731;\n\nSET max_rows_to_read = 0;\n\nSELECT count() FROM test.hits WHERE toInt16(CounterID) = 1731;\nSELECT count() FROM test.hits WHERE toInt8(CounterID) = toInt8(1731);\n\nSELECT count() FROM test.hits WHERE toDate(toUInt16(CounterID)) = toDate(1731);\n\nSELECT uniq(CounterID), uniqUpTo(5)(toInt8(CounterID)), count() FROM test.hits WHERE toInt8(CounterID + 1 - 1) = toInt8(1731);\nSELECT uniq(CounterID), uniqUpTo(5)(toInt8(CounterID)), count() FROM test.hits WHERE toInt8(CounterID) = toInt8(1731);\n\nSELECT uniq(CounterID), uniqUpTo(5)(toInt16(CounterID)), count() FROM test.hits WHERE toInt16(CounterID + 1 - 1) = 1731;\nSELECT uniq(CounterID), uniqUpTo(5)(toInt16(CounterID)), count() FROM test.hits WHERE toInt16(CounterID) = 1731;\n\nSET max_rows_to_read = 500000;\n\nSELECT uniq(CounterID), count() FROM test.hits WHERE toString(CounterID) = '1731';\n\nSET max_rows_to_read = 2200000;\n\nSELECT count() FROM test.hits WHERE CounterID < 732797;\nSELECT count() FROM test.hits WHERE CounterID <= 732797;\nSELECT count() FROM test.hits WHERE CounterID < 732797 AND CounterID > 107931;\nSELECT count() FROM test.hits WHERE CounterID < 732797 AND CounterID >= 107931;\nSELECT count() FROM test.hits WHERE CounterID <= 732797 AND CounterID > 107931;\nSELECT count() FROM test.hits WHERE CounterID <= 732797 AND CounterID >= 107931;\nSELECT count() FROM test.hits WHERE -CounterID > -732797;\nSELECT count() FROM test.hits WHERE -CounterID >= -732797;\nSELECT count() FROM test.hits WHERE -CounterID > -732797 AND CounterID > 107931;\nSELECT count() FROM test.hits WHERE -CounterID > -732797 AND CounterID >= 107931;\nSELECT count() FROM test.hits WHERE -CounterID >= -732797 AND CounterID > 107931;\nSELECT count() FROM test.hits WHERE -CounterID >= -732797 AND CounterID >= 107931;\nSELECT count() FROM test.hits WHERE CounterID < 732797 AND -CounterID < -107931;\nSELECT count() FROM test.hits WHERE CounterID < 732797 AND -CounterID <= -107931;\nSELECT count() FROM test.hits WHERE CounterID <= 732797 AND -CounterID < -107931;\nSELECT count() FROM test.hits WHERE CounterID <= 732797 AND -CounterID <= -107931;\n\nSET max_rows_to_read = 0;\n\nSELECT count() FROM test.hits WHERE EventDate = '2014-03-20';\nSELECT count() FROM test.hits WHERE toDayOfMonth(EventDate) = 20;\nSELECT count() FROM test.hits WHERE toDayOfWeek(EventDate) = 4;\nSELECT count() FROM test.hits WHERE toUInt16(EventDate) = toUInt16(toDate('2014-03-20'));\nSELECT count() FROM test.hits WHERE toInt64(EventDate) = toInt64(toDate('2014-03-20'));\nSELECT count() FROM test.hits WHERE toDateTime(EventDate) = '2014-03-20 00:00:00';\n\nSET max_rows_to_read = 50000;\n\nSELECT count() FROM test.hits WHERE toMonth(EventDate) != 3;\nSELECT count() FROM test.hits WHERE toYear(EventDate) != 2014;\nSELECT count() FROM test.hits WHERE toDayOfMonth(EventDate) > 23 OR toDayOfMonth(EventDate) < 17;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00149_quantiles_timing_distributed.sql",
    "content": "-- Tags: distributed\n\nSELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID);\nSELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID) SETTINGS optimize_aggregation_in_order = 1;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00150_quantiles_timing_precision.sql",
    "content": "SELECT CounterID, quantileTiming(0.5)(SendTiming) AS qt, least(30000, quantileExact(0.5)(SendTiming)) AS qe, count() AS c, round(abs(qt - qe) / greatest(qt, qe) AS diff, 3) AS rounded_diff FROM test.hits WHERE SendTiming != -1 GROUP BY CounterID HAVING diff != 0 ORDER BY diff DESC;\nSELECT CounterID, quantileTiming(0.5)(SendTiming) AS qt, least(30000, quantileExact(0.5)(SendTiming)) AS qe, count() AS c, round(abs(qt - qe) / greatest(qt, qe) AS diff, 3) AS rounded_diff FROM test.hits WHERE SendTiming != -1 GROUP BY CounterID HAVING diff != 0 ORDER BY diff DESC SETTINGS optimize_aggregation_in_order = 1;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00151_order_by_read_in_order.sql",
    "content": "SET optimize_read_in_order = 1;\nSELECT CounterID FROM test.hits ORDER BY CounterID DESC LIMIT 50;\nSELECT CounterID FROM test.hits ORDER BY CounterID LIMIT 50;\nSELECT CounterID FROM test.hits ORDER BY CounterID, EventDate LIMIT 50;\nSELECT EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50;\nSELECT EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50;\nSELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50;\nSELECT CounterID FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50;\nSELECT EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50;\n\nSELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50;\nSELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50;\nSELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate LIMIT 50;\nSELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00152_insert_different_granularity.sql",
    "content": "-- Tags: no-tsan, no-replicated-database, no-parallel\n-- Tag no-replicated-database: Fails due to additional replicas or shards\n\nDROP TABLE IF EXISTS fixed_granularity_table;\n\nCREATE TABLE fixed_granularity_table (`WatchID` UInt64, `JavaEnable` UInt8, `Title` String, `GoodEvent` Int16, `EventTime` DateTime, `EventDate` Date, `CounterID` UInt32, `ClientIP` UInt32, `ClientIP6` FixedString(16), `RegionID` UInt32, `UserID` UInt64, `CounterClass` Int8, `OS` UInt8, `UserAgent` UInt8, `URL` String, `Referer` String, `URLDomain` String, `RefererDomain` String, `Refresh` UInt8, `IsRobot` UInt8, `RefererCategories` Array(UInt16), `URLCategories` Array(UInt16), `URLRegions` Array(UInt32), `RefererRegions` Array(UInt32), `ResolutionWidth` UInt16, `ResolutionHeight` UInt16, `ResolutionDepth` UInt8, `FlashMajor` UInt8, `FlashMinor` UInt8, `FlashMinor2` String, `NetMajor` UInt8, `NetMinor` UInt8, `UserAgentMajor` UInt16, `UserAgentMinor` FixedString(2), `CookieEnable` UInt8, `JavascriptEnable` UInt8, `IsMobile` UInt8, `MobilePhone` UInt8, `MobilePhoneModel` String, `Params` String, `IPNetworkID` UInt32, `TraficSourceID` Int8, `SearchEngineID` UInt16, `SearchPhrase` String, `AdvEngineID` UInt8, `IsArtifical` UInt8, `WindowClientWidth` UInt16, `WindowClientHeight` UInt16, `ClientTimeZone` Int16, `ClientEventTime` DateTime, `SilverlightVersion1` UInt8, `SilverlightVersion2` UInt8, `SilverlightVersion3` UInt32, `SilverlightVersion4` UInt16, `PageCharset` String, `CodeVersion` UInt32, `IsLink` UInt8, `IsDownload` UInt8, `IsNotBounce` UInt8, `FUniqID` UInt64, `HID` UInt32, `IsOldCounter` UInt8, `IsEvent` UInt8, `IsParameter` UInt8, `DontCountHits` UInt8, `WithHash` UInt8, `HitColor` FixedString(1), `UTCEventTime` DateTime, `Age` UInt8, `Sex` UInt8, `Income` UInt8, `Interests` UInt16, `Robotness` UInt8, `GeneralInterests` Array(UInt16), `RemoteIP` UInt32, `RemoteIP6` FixedString(16), `WindowName` Int32, `OpenerName` Int32, `HistoryLength` Int16, `BrowserLanguage` FixedString(2), `BrowserCountry` FixedString(2), `SocialNetwork` String, `SocialAction` String, `HTTPError` UInt16, `SendTiming` Int32, `DNSTiming` Int32, `ConnectTiming` Int32, `ResponseStartTiming` Int32, `ResponseEndTiming` Int32, `FetchTiming` Int32, `RedirectTiming` Int32, `DOMInteractiveTiming` Int32, `DOMContentLoadedTiming` Int32, `DOMCompleteTiming` Int32, `LoadEventStartTiming` Int32, `LoadEventEndTiming` Int32, `NSToDOMContentLoadedTiming` Int32, `FirstPaintTiming` Int32, `RedirectCount` Int8, `SocialSourceNetworkID` UInt8, `SocialSourcePage` String, `ParamPrice` Int64, `ParamOrderID` String, `ParamCurrency` FixedString(3), `ParamCurrencyID` UInt16, `GoalsReached` Array(UInt32), `OpenstatServiceName` String, `OpenstatCampaignID` String, `OpenstatAdID` String, `OpenstatSourceID` String, `UTMSource` String, `UTMMedium` String, `UTMCampaign` String, `UTMContent` String, `UTMTerm` String, `FromTag` String, `HasGCLID` UInt8, `RefererHash` UInt64, `URLHash` UInt64, `CLID` UInt32, `YCLID` UInt64, `ShareService` String, `ShareURL` String, `ShareTitle` String, `ParsedParams.Key1` Array(String), `ParsedParams.Key2` Array(String), `ParsedParams.Key3` Array(String), `ParsedParams.Key4` Array(String), `ParsedParams.Key5` Array(String), `ParsedParams.ValueDouble` Array(Float64), `IslandID` FixedString(16), `RequestNum` UInt32, `RequestTry` UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192, index_granularity_bytes=0, min_bytes_for_wide_part = 0; -- looks like default table before update\n\nALTER TABLE fixed_granularity_table REPLACE PARTITION 201403 FROM test.hits;\n\nINSERT INTO fixed_granularity_table SELECT * FROM test.hits LIMIT 10; -- should still have non adaptive granularity\n\nINSERT INTO fixed_granularity_table SELECT * FROM test.hits LIMIT 10;\n\n-- We have removed testing of OPTIMIZE because it's too heavy on very slow builds (debug + coverage + thread fuzzer with sleeps)\n-- OPTIMIZE TABLE fixed_granularity_table FINAL; -- and even after optimize\n\nDETACH TABLE fixed_granularity_table;\n\nATTACH TABLE fixed_granularity_table;\n\nALTER TABLE fixed_granularity_table DETACH PARTITION 201403;\n\nALTER TABLE fixed_granularity_table ATTACH PARTITION 201403;\n\nSELECT count() from fixed_granularity_table;\n\nDROP TABLE IF EXISTS fixed_granularity_table;\n\nALTER TABLE test.hits DETACH PARTITION 201403;\n\nALTER TABLE test.hits ATTACH PARTITION 201403;\n\nDROP TABLE IF EXISTS hits_copy;\n\nCREATE TABLE hits_copy (`WatchID` UInt64, `JavaEnable` UInt8, `Title` String, `GoodEvent` Int16, `EventTime` DateTime, `EventDate` Date, `CounterID` UInt32, `ClientIP` UInt32, `ClientIP6` FixedString(16), `RegionID` UInt32, `UserID` UInt64, `CounterClass` Int8, `OS` UInt8, `UserAgent` UInt8, `URL` String, `Referer` String, `URLDomain` String, `RefererDomain` String, `Refresh` UInt8, `IsRobot` UInt8, `RefererCategories` Array(UInt16), `URLCategories` Array(UInt16), `URLRegions` Array(UInt32), `RefererRegions` Array(UInt32), `ResolutionWidth` UInt16, `ResolutionHeight` UInt16, `ResolutionDepth` UInt8, `FlashMajor` UInt8, `FlashMinor` UInt8, `FlashMinor2` String, `NetMajor` UInt8, `NetMinor` UInt8, `UserAgentMajor` UInt16, `UserAgentMinor` FixedString(2), `CookieEnable` UInt8, `JavascriptEnable` UInt8, `IsMobile` UInt8, `MobilePhone` UInt8, `MobilePhoneModel` String, `Params` String, `IPNetworkID` UInt32, `TraficSourceID` Int8, `SearchEngineID` UInt16, `SearchPhrase` String, `AdvEngineID` UInt8, `IsArtifical` UInt8, `WindowClientWidth` UInt16, `WindowClientHeight` UInt16, `ClientTimeZone` Int16, `ClientEventTime` DateTime, `SilverlightVersion1` UInt8, `SilverlightVersion2` UInt8, `SilverlightVersion3` UInt32, `SilverlightVersion4` UInt16, `PageCharset` String, `CodeVersion` UInt32, `IsLink` UInt8, `IsDownload` UInt8, `IsNotBounce` UInt8, `FUniqID` UInt64, `HID` UInt32, `IsOldCounter` UInt8, `IsEvent` UInt8, `IsParameter` UInt8, `DontCountHits` UInt8, `WithHash` UInt8, `HitColor` FixedString(1), `UTCEventTime` DateTime, `Age` UInt8, `Sex` UInt8, `Income` UInt8, `Interests` UInt16, `Robotness` UInt8, `GeneralInterests` Array(UInt16), `RemoteIP` UInt32, `RemoteIP6` FixedString(16), `WindowName` Int32, `OpenerName` Int32, `HistoryLength` Int16, `BrowserLanguage` FixedString(2), `BrowserCountry` FixedString(2), `SocialNetwork` String, `SocialAction` String, `HTTPError` UInt16, `SendTiming` Int32, `DNSTiming` Int32, `ConnectTiming` Int32, `ResponseStartTiming` Int32, `ResponseEndTiming` Int32, `FetchTiming` Int32, `RedirectTiming` Int32, `DOMInteractiveTiming` Int32, `DOMContentLoadedTiming` Int32, `DOMCompleteTiming` Int32, `LoadEventStartTiming` Int32, `LoadEventEndTiming` Int32, `NSToDOMContentLoadedTiming` Int32, `FirstPaintTiming` Int32, `RedirectCount` Int8, `SocialSourceNetworkID` UInt8, `SocialSourcePage` String, `ParamPrice` Int64, `ParamOrderID` String, `ParamCurrency` FixedString(3), `ParamCurrencyID` UInt16, `GoalsReached` Array(UInt32), `OpenstatServiceName` String, `OpenstatCampaignID` String, `OpenstatAdID` String, `OpenstatSourceID` String, `UTMSource` String, `UTMMedium` String, `UTMCampaign` String, `UTMContent` String, `UTMTerm` String, `FromTag` String, `HasGCLID` UInt8, `RefererHash` UInt64, `URLHash` UInt64, `CLID` UInt32, `YCLID` UInt64, `ShareService` String, `ShareURL` String, `ShareTitle` String, `ParsedParams.Key1` Array(String), `ParsedParams.Key2` Array(String), `ParsedParams.Key3` Array(String), `ParsedParams.Key4` Array(String), `ParsedParams.Key5` Array(String), `ParsedParams.ValueDouble` Array(Float64), `IslandID` FixedString(16), `RequestNum` UInt32, `RequestTry` UInt8)\n    ENGINE = MergeTree()\n    PARTITION BY toYYYYMM(EventDate)\n    ORDER BY (CounterID, EventDate, intHash32(UserID))\n    SAMPLE BY intHash32(UserID)\n    SETTINGS index_granularity=8192, min_bytes_for_wide_part = 0;\n\nALTER TABLE hits_copy REPLACE PARTITION 201403 FROM test.hits;\n\n-- It's important to test table, which were created before server update\nINSERT INTO test.hits SELECT * FROM hits_copy LIMIT 100;\n\nALTER TABLE test.hits DETACH PARTITION 201403;\n\nALTER TABLE test.hits ATTACH PARTITION 201403;\n\n-- OPTIMIZE TABLE test.hits;\n\nSELECT count() FROM test.hits;\n\n-- restore hits\nALTER TABLE test.hits REPLACE PARTITION 201403 FROM hits_copy;\n\nDROP TABLE IF EXISTS hits_copy;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00153_aggregate_arena_race.sql",
    "content": "-- Tags: race\n\ncreate temporary table dest00153 (`s` AggregateFunction(groupUniqArray, String)) engine Memory;\ninsert into dest00153 select groupUniqArrayState(RefererDomain) from test.hits group by URLDomain;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00154_avro.sql",
    "content": "-- Tags: no-fasttest\n\nDROP TABLE IF EXISTS test.avro;\n\nSET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage\n\nCREATE TABLE test.avro AS test.hits ENGINE = File(Avro);\nINSERT INTO test.avro SELECT * FROM test.hits LIMIT 10000;\n\nSELECT sum(cityHash64(*)) FROM (SELECT * FROM test.hits LIMIT 10000);\nSELECT sum(cityHash64(*)) FROM test.avro;\n\nDROP TABLE test.avro;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00156_max_execution_speed_sample_merge.sql",
    "content": "SET max_execution_speed = 4000000, timeout_before_checking_execution_speed = 0;\n\nCREATE TEMPORARY TABLE times (t DateTime);\n\nINSERT INTO times SELECT now();\nSELECT count() FROM test.hits SAMPLE 1 / 2;\nINSERT INTO times SELECT now();\n\nSELECT max(t) - min(t) >= 1 FROM times;\nTRUNCATE TABLE times;\n\nINSERT INTO times SELECT now();\nSELECT count() FROM merge(test, '^hits$') SAMPLE 1 / 2;\nINSERT INTO times SELECT now();\n\nSELECT max(t) - min(t) >= 1 FROM times;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00157_cache_dictionary.sql",
    "content": "-- Tags: no-tsan, no-parallel\n\nDROP TABLE IF EXISTS test.hits_1m;\nCREATE TABLE test.hits_1m as test.hits;\nINSERT INTO test.hits_1m SELECT * FROM test.hits LIMIT 1000000;\n\nCREATE DATABASE IF NOT EXISTS db_dict;\n--DROP DICTIONARY IF EXISTS db_dict.cache_hits;\n\n/*\nCREATE DICTIONARY db_dict.cache_hits\n(WatchID UInt64, UserID UInt64, SearchPhrase String)\nPRIMARY KEY WatchID\nSOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'hits_1m' PASSWORD '' DB 'test'))\nLIFETIME(MIN 1 MAX 10)\nLAYOUT(CACHE(SIZE_IN_CELLS 1 QUERY_WAIT_TIMEOUT_MILLISECONDS 60000));\n */\n\nSELECT count() FROM (SELECT WatchID, arrayDistinct(groupArray(dictGetUInt64( 'db_dict.cache_hits', 'UserID', toUInt64(WatchID)))) as arr\nFROM test.hits_1m PREWHERE WatchID % 5 == 0 GROUP BY  WatchID order by length(arr) desc) WHERE arr = [0];\n\nSELECT count() FROM (SELECT WatchID, arrayDistinct(groupArray(dictGetUInt64( 'db_dict.cache_hits', 'UserID', toUInt64(WatchID)))) as arr\nFROM test.hits_1m PREWHERE WatchID % 7 == 0 GROUP BY  WatchID order by length(arr) desc) WHERE arr = [0];\n\nSELECT count() FROM (SELECT WatchID, arrayDistinct(groupArray(dictGetUInt64( 'db_dict.cache_hits', 'UserID', toUInt64(WatchID)))) as arr\nFROM test.hits_1m PREWHERE WatchID % 13 == 0 GROUP BY  WatchID order by length(arr) desc) WHERE arr = [0];\n\nDROP DICTIONARY IF EXISTS db_dict.cache_hits;\nDROP DATABASE IF  EXISTS db_dict;\nDROP TABLE IF EXISTS hits_1m;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00158_cache_dictionary_has.sql",
    "content": "-- Tags: no-parallel\n\nCREATE DATABASE IF NOT EXISTS db_dict;\nDROP DICTIONARY IF EXISTS db_dict.cache_hits;\n\n/*\nCREATE DICTIONARY db_dict.cache_hits\n(WatchID UInt64, UserID UInt64, SearchPhrase String)\nPRIMARY KEY WatchID\nSOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'hits' PASSWORD '' DB 'test'))\nLIFETIME(MIN 300 MAX 600)\nLAYOUT(CACHE(SIZE_IN_CELLS 100 QUERY_WAIT_TIMEOUT_MILLISECONDS 600000));\n*/\n\nSELECT sum(flag) FROM (SELECT dictHas('db_dict.cache_hits', toUInt64(WatchID)) as flag FROM test.hits PREWHERE WatchID % 1400 == 0 LIMIT 100);\nSELECT count() from test.hits PREWHERE WatchID % 1400 == 0;\n\nSELECT sum(flag) FROM (SELECT dictHas('db_dict.cache_hits', toUInt64(WatchID)) as flag FROM test.hits PREWHERE WatchID % 350 == 0 LIMIT 100);\nSELECT count() from test.hits PREWHERE WatchID % 350 == 0;\n\nSELECT sum(flag) FROM (SELECT dictHas('db_dict.cache_hits', toUInt64(WatchID)) as flag FROM test.hits PREWHERE WatchID % 5 == 0 LIMIT 100);\nSELECT count() from test.hits PREWHERE WatchID % 5 == 0;\n\nDROP DICTIONARY IF EXISTS db_dict.cache_hits;\nDROP DATABASE IF  EXISTS db_dict;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00160_decode_xml_component.sql",
    "content": "SELECT sum(DISTINCT sipHash64(decodeXMLComponent(Title) AS decoded)) FROM test.hits WHERE Title != decoded;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00162_mmap_compression_none.sql",
    "content": "DROP TABLE IF EXISTS hits_none;\nCREATE TABLE hits_none (Title String CODEC(NONE)) ENGINE = MergeTree ORDER BY tuple();\nINSERT INTO hits_none SELECT Title FROM test.hits;\n\nSET min_bytes_to_use_mmap_io = 1;\nSELECT sum(length(Title)) FROM hits_none;\n\nDROP TABLE hits_none;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00164_quantileBfloat16.sql",
    "content": "SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\nSELECT CounterID AS k, quantilesBFloat16(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\n\n\nSELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\nSELECT CounterID AS k, quantilesBFloat16(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00165_jit_aggregate_functions.sql",
    "content": "SET compile_aggregate_expressions = 1;\nSET min_count_to_compile_aggregate_expression = 0;\n\nSELECT 'Aggregation using JIT compilation';\n\nSELECT 'Simple functions';\n\nSELECT\n    CounterID,\n    min(WatchID),\n    max(WatchID),\n    sum(WatchID),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nGROUP BY CounterID ORDER BY count() DESC LIMIT 20;\n\nSELECT 'Simple functions with non compilable function';\n\nSELECT\n    CounterID,\n    min(WatchID),\n    max(WatchID),\n    sum(WatchID),\n    sum(toUInt128(WatchID)),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nGROUP BY CounterID ORDER BY count() DESC LIMIT 20;\n\nSELECT 'Simple functions if combinator';\n\nWITH (WatchID % 2 == 0) AS predicate\nSELECT\n    CounterID,\n    minIf(WatchID,predicate),\n    maxIf(WatchID, predicate),\n    sumIf(WatchID, predicate),\n    avgIf(WatchID, predicate),\n    avgWeightedIf(WatchID, CounterID, predicate),\n    countIf(WatchID, predicate),\n    groupBitOrIf(WatchID, predicate),\n    groupBitAndIf(WatchID, predicate),\n    groupBitXorIf(WatchID, predicate)\nFROM test.hits\nGROUP BY CounterID ORDER BY count() DESC LIMIT 20;\n\nSELECT 'Simple functions without key';\n\nSELECT\n    min(WatchID) AS min_watch_id,\n    max(WatchID),\n    sum(WatchID),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nORDER BY min_watch_id DESC LIMIT 20;\n\nSELECT 'Simple functions with non compilable function without key';\n\nSELECT\n    min(WatchID) AS min_watch_id,\n    max(WatchID),\n    sum(WatchID),\n    sum(toUInt128(WatchID)),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nORDER BY min_watch_id DESC LIMIT 20;\n\nSELECT 'Simple functions if combinator without key';\n\nWITH (WatchID % 2 == 0) AS predicate\nSELECT\n    minIf(WatchID, predicate) as min_watch_id,\n    maxIf(WatchID, predicate),\n    sumIf(WatchID, predicate),\n    avgIf(WatchID, predicate),\n    avgWeightedIf(WatchID, CounterID, predicate),\n    countIf(WatchID, predicate),\n    groupBitOrIf(WatchID, predicate),\n    groupBitAndIf(WatchID, predicate),\n    groupBitXorIf(WatchID, predicate)\nFROM test.hits\nORDER BY min_watch_id\nDESC LIMIT 20;\n\nSET compile_aggregate_expressions = 0;\n\nSELECT 'Aggregation without JIT compilation';\n\nSELECT 'Simple functions';\n\nSELECT\n    CounterID,\n    min(WatchID),\n    max(WatchID),\n    sum(WatchID),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nGROUP BY CounterID ORDER BY count() DESC LIMIT 20;\n\nSELECT 'Simple functions with non compilable function';\nSELECT\n    CounterID,\n    min(WatchID),\n    max(WatchID),\n    sum(WatchID),\n    sum(toUInt128(WatchID)),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nGROUP BY CounterID ORDER BY count() DESC LIMIT 20;\n\nSELECT 'Simple functions if combinator';\n\nWITH (WatchID % 2 == 0) AS predicate\nSELECT\n    CounterID,\n    minIf(WatchID,predicate),\n    maxIf(WatchID, predicate),\n    sumIf(WatchID, predicate),\n    avgIf(WatchID, predicate),\n    avgWeightedIf(WatchID, CounterID, predicate),\n    countIf(WatchID, predicate),\n    groupBitOrIf(WatchID, predicate),\n    groupBitAndIf(WatchID, predicate),\n    groupBitXorIf(WatchID, predicate)\nFROM test.hits\nGROUP BY CounterID ORDER BY count() DESC LIMIT 20;\n\nSELECT 'Simple functions without key';\n\nSELECT\n    min(WatchID) AS min_watch_id,\n    max(WatchID),\n    sum(WatchID),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nORDER BY min_watch_id DESC LIMIT 20;\n\nSELECT 'Simple functions with non compilable function without key';\n\nSELECT\n    min(WatchID) AS min_watch_id,\n    max(WatchID),\n    sum(WatchID),\n    sum(toUInt128(WatchID)),\n    avg(WatchID),\n    avgWeighted(WatchID, CounterID),\n    count(WatchID),\n    groupBitOr(WatchID),\n    groupBitAnd(WatchID),\n    groupBitXor(WatchID)\nFROM test.hits\nORDER BY min_watch_id DESC LIMIT 20;\n\nSELECT 'Simple functions if combinator without key';\n\nWITH (WatchID % 2 == 0) AS predicate\nSELECT\n    minIf(WatchID, predicate) as min_watch_id,\n    maxIf(WatchID, predicate),\n    sumIf(WatchID, predicate),\n    avgIf(WatchID, predicate),\n    avgWeightedIf(WatchID, CounterID, predicate),\n    countIf(WatchID, predicate),\n    groupBitOrIf(WatchID, predicate),\n    groupBitAndIf(WatchID, predicate),\n    groupBitXorIf(WatchID, predicate)\nFROM test.hits\nORDER BY min_watch_id\nDESC LIMIT 20;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00166_explain_estimate.sql",
    "content": "-- Tags: no-replicated-database\n-- Tag no-replicated-database: Requires investigation\n\nEXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID = 29103473;\nEXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID != 29103473;\nEXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID > 29103473;\nEXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID < 29103473;\nEXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID = 29103473 UNION ALL SELECT count() FROM test.hits WHERE CounterID = 1704509;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00167_read_bytes_from_fs.sql",
    "content": "-- Tags: no-random-settings\n\nSELECT sum(cityHash64(*)) FROM test.hits SETTINGS max_threads=40;\n\n-- We had a bug which lead to additional compressed data read. test.hits compressed size is about 1.2Gb, but we read more then 3Gb.\n-- Small additional reads still possible, so we compare with about 1.5Gb.\nSYSTEM FLUSH LOGS;\n\nSELECT ProfileEvents['ReadBufferFromFileDescriptorReadBytes'] < 1500000000 from system.query_log where query = 'SELECT sum(cityHash64(*)) FROM test.hits SETTINGS max_threads=40;' and current_database = currentDatabase() and type = 'QueryFinish';\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00169_contingency.sql",
    "content": "WITH URLDomain AS a, URLDomain AS b\nSELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits;\n\nWITH URLDomain AS a, RefererDomain AS b\nSELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits;\n\nWITH URLDomain AS a, CounterID AS b\nSELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits;\n\nWITH ClientIP AS a, RemoteIP AS b\nSELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits;\n\nWITH ResolutionWidth AS a, ResolutionHeight AS b\nSELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00170_s3_cache.sql",
    "content": "-- Tags: no-parallel, no-random-settings\n\n-- { echo }\n\nSET allow_prefetched_read_pool_for_remote_filesystem=0;\nSET enable_filesystem_cache_on_write_operations=0;\nSET max_memory_usage='20G';\nSYSTEM DROP FILESYSTEM CACHE;\nSELECT count() FROM test.hits_s3;\nSELECT count() FROM test.hits_s3 WHERE AdvEngineID != 0;\nSELECT sum(AdvEngineID), count(), avg(ResolutionWidth) FROM test.hits_s3 ;\nSELECT sum(UserID) FROM test.hits_s3 ;\nSELECT uniq(UserID) FROM test.hits_s3 ;\nSELECT uniq(SearchPhrase) FROM test.hits_s3 ;\nSELECT min(EventDate), max(EventDate) FROM test.hits_s3 ;\nSELECT AdvEngineID, count() FROM test.hits_s3 WHERE AdvEngineID != 0 GROUP BY AdvEngineID ORDER BY AdvEngineID DESC;\nSELECT RegionID, uniq(UserID) AS u FROM test.hits_s3 GROUP BY RegionID ORDER BY u DESC LIMIT 10;\nSELECT RegionID, sum(AdvEngineID), count() AS c, avg(ResolutionWidth), uniq(UserID) FROM test.hits_s3 GROUP BY RegionID ORDER BY c DESC LIMIT 10;\nSELECT MobilePhoneModel, uniq(UserID) AS u FROM test.hits_s3 WHERE MobilePhoneModel != '' GROUP BY MobilePhoneModel ORDER BY u DESC LIMIT 10;\nSELECT MobilePhone, MobilePhoneModel, uniq(UserID) AS u FROM test.hits_s3 WHERE MobilePhoneModel != '' GROUP BY MobilePhone, MobilePhoneModel ORDER BY u DESC LIMIT 10;\nSELECT uniq(SearchPhrase), count() AS c FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10;\nSELECT uniq(SearchPhrase), uniq(UserID) AS u FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchPhrase ORDER BY u DESC LIMIT 10;\nSELECT SearchEngineID, uniq(SearchPhrase), count() AS c FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchEngineID, SearchPhrase ORDER BY c DESC LIMIT 10;\nSELECT UserID, count() FROM test.hits_s3 GROUP BY UserID ORDER BY count() DESC LIMIT 10;\nSELECT UserID, uniq(SearchPhrase) as m, count() as c FROM test.hits_s3 GROUP BY UserID, SearchPhrase ORDER BY UserID, m, c DESC LIMIT 10;\nSELECT UserID, uniq(SearchPhrase) as m, count() as c FROM test.hits_s3 GROUP BY UserID, SearchPhrase ORDER BY UserID, m, c LIMIT 10;\nSELECT UserID, toMinute(EventTime) AS m, uniq(SearchPhrase) as u, count() as c FROM test.hits_s3 GROUP BY UserID, m, SearchPhrase ORDER BY UserID DESC LIMIT 10 FORMAT Null;\nSELECT UserID FROM test.hits_s3 WHERE UserID = 12345678901234567890;\nSELECT count() FROM test.hits_s3 WHERE URL LIKE '%metrika%';\nSELECT uniq(SearchPhrase) as u, max(URL) as m, count() AS c FROM test.hits_s3 WHERE URL LIKE '%metrika%' AND SearchPhrase != '' GROUP BY SearchPhrase ORDER BY u, m, c DESC LIMIT 10;\nSELECT uniq(SearchPhrase), max(URL), max(Title), count() AS c, uniq(UserID) FROM test.hits_s3 WHERE Title LIKE '%Яндекс%' AND URL NOT LIKE '%.yandex.%' AND SearchPhrase != '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10;\nSELECT * FROM test.hits_s3 WHERE URL LIKE '%metrika%' ORDER BY EventTime LIMIT 10 format Null;\nSELECT SearchPhrase FROM test.hits_s3 WHERE SearchPhrase != '' ORDER BY EventTime LIMIT 10 FORMAT Null;\nSELECT SearchPhrase FROM test.hits_s3 WHERE SearchPhrase != '' ORDER BY SearchPhrase LIMIT 10 FORMAT Null;\nSELECT SearchPhrase FROM test.hits_s3 WHERE SearchPhrase != '' ORDER BY EventTime, SearchPhrase LIMIT 10 FORMAT Null;\nSELECT CounterID, avg(length(URL)) AS l, count() AS c FROM test.hits_s3 WHERE URL != '' GROUP BY CounterID HAVING c > 100000 ORDER BY l DESC LIMIT 25;\nSELECT domainWithoutWWW(Referer) AS key, avg(length(Referer)) AS l, count() AS c, max(Referer) FROM test.hits_s3 WHERE Referer != '' GROUP BY key HAVING c > 100000 ORDER BY l DESC LIMIT 25;\nSELECT sum(ResolutionWidth), sum(ResolutionWidth + 1), sum(ResolutionWidth + 2), sum(ResolutionWidth + 3), sum(ResolutionWidth + 4), sum(ResolutionWidth + 5), sum(ResolutionWidth + 6), sum(ResolutionWidth + 7), sum(ResolutionWidth + 8), sum(ResolutionWidth + 9), sum(ResolutionWidth + 10), sum(ResolutionWidth + 11), sum(ResolutionWidth + 12), sum(ResolutionWidth + 13), sum(ResolutionWidth + 14), sum(ResolutionWidth + 15), sum(ResolutionWidth + 16), sum(ResolutionWidth + 17), sum(ResolutionWidth + 18), sum(ResolutionWidth + 19), sum(ResolutionWidth + 20), sum(ResolutionWidth + 21), sum(ResolutionWidth + 22), sum(ResolutionWidth + 23), sum(ResolutionWidth + 24), sum(ResolutionWidth + 25), sum(ResolutionWidth + 26), sum(ResolutionWidth + 27), sum(ResolutionWidth + 28), sum(ResolutionWidth + 29), sum(ResolutionWidth + 30), sum(ResolutionWidth + 31), sum(ResolutionWidth + 32), sum(ResolutionWidth + 33), sum(ResolutionWidth + 34), sum(ResolutionWidth + 35), sum(ResolutionWidth + 36), sum(ResolutionWidth + 37), sum(ResolutionWidth + 38), sum(ResolutionWidth + 39), sum(ResolutionWidth + 40), sum(ResolutionWidth + 41), sum(ResolutionWidth + 42), sum(ResolutionWidth + 43), sum(ResolutionWidth + 44), sum(ResolutionWidth + 45), sum(ResolutionWidth + 46), sum(ResolutionWidth + 47), sum(ResolutionWidth + 48), sum(ResolutionWidth + 49), sum(ResolutionWidth + 50), sum(ResolutionWidth + 51), sum(ResolutionWidth + 52), sum(ResolutionWidth + 53), sum(ResolutionWidth + 54), sum(ResolutionWidth + 55), sum(ResolutionWidth + 56), sum(ResolutionWidth + 57), sum(ResolutionWidth + 58), sum(ResolutionWidth + 59), sum(ResolutionWidth + 60), sum(ResolutionWidth + 61), sum(ResolutionWidth + 62), sum(ResolutionWidth + 63), sum(ResolutionWidth + 64), sum(ResolutionWidth + 65), sum(ResolutionWidth + 66), sum(ResolutionWidth + 67), sum(ResolutionWidth + 68), sum(ResolutionWidth + 69), sum(ResolutionWidth + 70), sum(ResolutionWidth + 71), sum(ResolutionWidth + 72), sum(ResolutionWidth + 73), sum(ResolutionWidth + 74), sum(ResolutionWidth + 75), sum(ResolutionWidth + 76), sum(ResolutionWidth + 77), sum(ResolutionWidth + 78), sum(ResolutionWidth + 79), sum(ResolutionWidth + 80), sum(ResolutionWidth + 81), sum(ResolutionWidth + 82), sum(ResolutionWidth + 83), sum(ResolutionWidth + 84), sum(ResolutionWidth + 85), sum(ResolutionWidth + 86), sum(ResolutionWidth + 87), sum(ResolutionWidth + 88), sum(ResolutionWidth + 89) FROM test.hits_s3;\nSELECT SearchEngineID, ClientIP, count() AS c, sum(Refresh), avg(ResolutionWidth) FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchEngineID, ClientIP ORDER BY c DESC LIMIT 10;\nSELECT WatchID, ClientIP, count() AS c, sum(Refresh), avg(ResolutionWidth) FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY WatchID, ClientIP ORDER BY c, WatchID DESC LIMIT 10;\nSELECT WatchID, ClientIP, count() AS c, sum(Refresh), avg(ResolutionWidth) FROM test.hits_s3 GROUP BY WatchID, ClientIP ORDER BY c, WatchID DESC LIMIT 10;\nSELECT URL, count() AS c FROM test.hits_s3 GROUP BY URL ORDER BY c DESC LIMIT 10;\nSELECT 1, URL, count() AS c FROM test.hits_s3 GROUP BY 1, URL ORDER BY c DESC LIMIT 10;\nSELECT ClientIP AS x, x - 1, x - 2, x - 3, count() AS c FROM test.hits_s3 GROUP BY x, x - 1, x - 2, x - 3 ORDER BY c DESC LIMIT 10;\nSELECT URL, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT DontCountHits AND NOT Refresh AND notEmpty(URL) GROUP BY URL ORDER BY PageViews DESC LIMIT 10;\nSELECT Title, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT DontCountHits AND NOT Refresh AND notEmpty(Title) GROUP BY Title ORDER BY PageViews, Title DESC LIMIT 10;\nSELECT URL, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh AND IsLink AND NOT IsDownload GROUP BY URL ORDER BY PageViews DESC LIMIT 1000;\nSELECT TraficSourceID, SearchEngineID, AdvEngineID, ((SearchEngineID = 0 AND AdvEngineID = 0) ? Referer : '') AS Src, URL AS Dst, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh GROUP BY TraficSourceID, SearchEngineID, AdvEngineID, Src, Dst ORDER BY PageViews, TraficSourceID DESC LIMIT 1000;\nSELECT URLHash, EventDate, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh AND TraficSourceID IN (-1, 6) AND RefererHash = halfMD5('http://example.ru/') GROUP BY URLHash, EventDate ORDER BY PageViews DESC LIMIT 100;\nSELECT WindowClientWidth, WindowClientHeight, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh AND NOT DontCountHits AND URLHash = halfMD5('http://example.ru/') GROUP BY WindowClientWidth, WindowClientHeight ORDER BY PageViews DESC LIMIT 10000;\nSELECT toStartOfMinute(EventTime) AS Minute, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-02' AND NOT Refresh AND NOT DontCountHits GROUP BY Minute ORDER BY Minute;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00171_grouping_aggregated_transform_bug.sql",
    "content": "-- Tags: distributed\n\nSELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID) SETTINGS max_block_size = 63169;\nSELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID) SETTINGS optimize_aggregation_in_order = 1, max_block_size = 63169;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00172_early_constant_folding.sql",
    "content": "-- Tags: no-parallel-replicas\n\nset max_threads=10;\nEXPLAIN PIPELINE SELECT count(JavaEnable) FROM test.hits WHERE WatchID = 1 OR Title = 'next' OR URL = 'prev' OR URL = '???' OR 1;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00173_group_by_use_nulls.sql",
    "content": "SELECT\n    CounterID AS k,\n    quantileBFloat16(0.5)(ResolutionWidth)\nFROM remote('127.0.0.{1,2}', test, hits)\nGROUP BY k\nORDER BY\n    count() DESC,\n    CounterID ASC\nLIMIT 10\nSETTINGS group_by_use_nulls = 1;\n\nSELECT\n    CounterID AS k,\n    quantileBFloat16(0.5)(ResolutionWidth)\nFROM test.hits\nGROUP BY k\nORDER BY\n    count() DESC,\n    CounterID ASC\nLIMIT 10\nSETTINGS group_by_use_nulls = 1 FORMAT Null;\n\n-- { echoOn }\nset allow_experimental_analyzer = 1;\n\nSELECT\n    CounterID AS k,\n    quantileBFloat16(0.5)(ResolutionWidth)\nFROM remote('127.0.0.{1,2}', test, hits)\nGROUP BY k\nORDER BY\n    count() DESC,\n    CounterID ASC\nLIMIT 10\nSETTINGS group_by_use_nulls = 1;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00174_distinct_in_order.sql",
    "content": "select '-- check that distinct with and w/o optimization produce the same result';\n\ndrop table if exists distinct_in_order sync;\ndrop table if exists ordinary_distinct sync;\n\nselect '-- DISTINCT columns are the same as in ORDER BY';\ncreate table distinct_in_order (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate);\ninsert into distinct_in_order select distinct CounterID, EventDate from test.hits order by CounterID, EventDate settings optimize_distinct_in_order=1;\ncreate table ordinary_distinct (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate);\ninsert into ordinary_distinct select distinct CounterID, EventDate from test.hits order by CounterID, EventDate settings optimize_distinct_in_order=0;\nselect distinct * from distinct_in_order except select * from ordinary_distinct;\n\ndrop table if exists distinct_in_order sync;\ndrop table if exists ordinary_distinct sync;\n\nselect '-- DISTINCT columns has prefix in ORDER BY columns';\ncreate table distinct_in_order (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate);\ninsert into distinct_in_order select distinct CounterID, EventDate from test.hits order by CounterID settings optimize_distinct_in_order=1;\ncreate table ordinary_distinct (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate);\ninsert into ordinary_distinct select distinct CounterID, EventDate from test.hits order by CounterID settings optimize_distinct_in_order=0;\nselect distinct * from distinct_in_order except select * from ordinary_distinct;\n\ndrop table if exists distinct_in_order sync;\ndrop table if exists ordinary_distinct sync;\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00175_counting_resources_in_subqueries.sql",
    "content": "-- the work for scalar subquery is properly accounted:\nSET max_rows_to_read = 1000000;\nSELECT 1 = (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 }\n\n-- the work for subquery in IN is properly accounted:\nSET max_rows_to_read = 1000000;\nSELECT 1 IN (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 }\n\n-- this query reads from the table twice:\nSET max_rows_to_read = 15000000;\nSELECT count() IN (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)) FROM test.hits WHERE NOT ignore(AdvEngineID); -- { serverError 158 }\n\n-- the resources are properly accounted even if the subquery is evaluated in advance to facilitate the index analysis.\n-- this query is using index and filter out the second reading pass.\nSET max_rows_to_read = 1000000;\nSELECT count() FROM test.hits WHERE CounterID > (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 }\n\n-- this query is using index but have to read all the data twice.\nSET max_rows_to_read = 10000000;\nSELECT count() FROM test.hits WHERE CounterID < (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 }\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00176_distinct_limit_by_limit_bug_43377.sql",
    "content": "SELECT count()\nFROM\n(\n    SELECT DISTINCT\n        Title,\n        SearchPhrase\n    FROM test.hits\n    WHERE (SearchPhrase != '') AND (NOT match(Title, '[а-яА-ЯёЁ]')) AND (NOT match(SearchPhrase, '[а-яА-ЯёЁ]'))\n    LIMIT 1 BY Title\n    LIMIT 10\n);\n"
  },
  {
    "path": "parser/testdata/query/compatible/1_stateful/00177_select_from_gcs.sql",
    "content": "SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/');"
  },
  {
    "path": "parser/testdata/query/create_window_view.sql",
    "content": "CREATE OR REPLACE VIEW asdf AS\nSELECT id,\n       price * 1.5 AS computed_value,\n       row_number() OVER (\n           PARTITION BY category\n           ORDER BY created_at\n           RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW\n           )       AS rn\nFROM source_table\nWHERE date >= '2023-01-01';\n"
  },
  {
    "path": "parser/testdata/query/format/access_tuple_with_dot.sql",
    "content": "-- Origin SQL:\nSELECT tuple('a','b','c').3, .1234;\n\nSELECT toTypeName( tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)),\n       (tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)).second,\n       tuple('a','b','c').3,\n       tupleElement(tuple('a','b','c'),1)\n\n-- Format SQL:\nSELECT tuple('a', 'b', 'c').3, .1234;\nSELECT toTypeName(tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)), (tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)).second, tuple('a', 'b', 'c').3, tupleElement(tuple('a', 'b', 'c'), 1);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/access_tuple_with_dot.sql",
    "content": "-- Origin SQL:\nSELECT tuple('a','b','c').3, .1234;\n\nSELECT toTypeName( tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)),\n       (tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)).second,\n       tuple('a','b','c').3,\n       tupleElement(tuple('a','b','c'),1)\n\n-- Beautify SQL:\nSELECT\n  tuple('a', 'b', 'c').3,\n  .1234;\nSELECT\n  toTypeName(tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)),\n  (tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)).second,\n  tuple('a', 'b', 'c').3,\n  tupleElement(tuple('a', 'b', 'c'), 1);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/create_window_view.sql",
    "content": "-- Origin SQL:\nCREATE OR REPLACE VIEW asdf AS\nSELECT id,\n       price * 1.5 AS computed_value,\n       row_number() OVER (\n           PARTITION BY category\n           ORDER BY created_at\n           RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW\n           )       AS rn\nFROM source_table\nWHERE date >= '2023-01-01';\n\n\n-- Beautify SQL:\nCREATE OR REPLACE VIEW asdf AS SELECT\n  id,\n  price * 1.5 AS computed_value,\n  row_number() OVER (PARTITION BY category ORDER BY\n    created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW) AS rn\nFROM\n  source_table\nWHERE\n  date >= '2023-01-01';\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/query_with_expr_compare.sql",
    "content": "-- Origin SQL:\nSELECT date, path, splitByChar('/', path)[2] AS path_b\nFROM(\n    SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date\n    )\nWHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30'\n  AND splitByChar('/', path)[1] = 'pathA'\n\n-- Beautify SQL:\nSELECT\n  date,\n  path,\n  splitByChar('/', path)[2] AS path_b\nFROM\n  (SELECT\n    'pathA/pathB/pathC' AS path,\n    '2024-09-10' AS date)\nWHERE\n  toDate(date) BETWEEN '2024-09-01' AND '2024-09-30'\nAND\n  splitByChar('/', path)[1] = 'pathA';\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_case_multiple_when.sql",
    "content": "-- Origin SQL:\nSELECT\n    *,\n    CASE\n        WHEN col2 = 'value1' THEN 'when1'\n        WHEN col3 = 'value2' THEN 'when2'\n        ELSE 'else'\n    END as check_result\nFROM table_name\nWHERE col1 = '123456789'\n\n\n-- Beautify SQL:\nSELECT\n  *,\n  CASE\n    WHEN col2 = 'value1' THEN 'when1'\n    WHEN col3 = 'value2' THEN 'when2'\n    ELSE 'else'\n  END AS check_result\nFROM\n  table_name\nWHERE\n  col1 = '123456789';\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_case_when_exists.sql",
    "content": "-- Origin SQL:\nSELECT\n    *,\n    CASE\n        WHEN EXISTS(SELECT 1\n    FROM table_name\n    WHERE col1 = '999999999')\n        THEN 'then'\n        ELSE 'else'\n    END as check_result\nFROM table_name\nWHERE col1 = '123456789'\n\n\n-- Beautify SQL:\nSELECT\n  *,\n  CASE\n    WHEN EXISTS(SELECT\n      1\n    FROM\n      table_name\n    WHERE\n      col1 = '999999999') THEN 'then'\n    ELSE 'else'\n  END AS check_result\nFROM\n  table_name\nWHERE\n  col1 = '123456789';\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_cast.sql",
    "content": "-- Origin SQL:\nselect cast(1 as Float64) as value;\nselect cast(1, 'Float64') as value;\nselect (1 as Float64) as value;\nselect 1::Float64 as value;\n\n-- Beautify SQL:\nSELECT\n  CAST(1 AS Float64) AS value;\nSELECT\n  CAST(1, 'Float64') AS value;\nSELECT\n  (1 AS Float64) AS value;\nSELECT\n  1::Float64 AS value;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_column_alias_string.sql",
    "content": "-- Origin SQL:\nSELECT 'abc' as \"value2\";\n\nSELECT $abc, a$$bc, abc$$;\n\n\n-- Beautify SQL:\nSELECT\n  'abc' AS \"value2\";\nSELECT\n  $abc,\n  a$$bc,\n  abc$$;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_concat_expr.sql",
    "content": "-- Origin SQL:\nSELECT 'a' || 'b';\nSELECT 'a' || 'b' || 'c';\nSELECT 'a' || 'b' || 'c' + 5;\n\n\n-- Beautify SQL:\nSELECT\n  'a' || 'b';\nSELECT\n  'a' || 'b' || 'c';\nSELECT\n  'a' || 'b' || 'c' + 5;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_expr.sql",
    "content": "-- Origin SQL:\nSELECT 1+1\n\n-- Beautify SQL:\nSELECT\n  1 + 1;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_extract_with_regex.sql",
    "content": "-- Origin SQL:\nSELECT\n  COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT\nFROM\n  test.table\nWHERE\n  app_id = 999118646\n  AND toUnixTimestamp(timestamp) >= 1740366695\n  AND toUnixTimestamp(timestamp) <= 1740377495\nGROUP BY\n  CASE\n    WHEN length(extract(instance, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN instance\n    ELSE '空'\n  END,\n  CASE\n    WHEN length(extract(client_ip, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN client_ip\n    ELSE '空'\n  END,\n  src_type,\n  node_class,\n  port,\n  client_port\nLIMIT 10000\n\n\n-- Beautify SQL:\nSELECT\n  COUNT(1),\n  SRC_TYPE,\n  NODE_CLASS,\n  PORT,\n  CLIENT_PORT\nFROM\n  test.table\nWHERE\n  app_id = 999118646\nAND\n  toUnixTimestamp(timestamp) >= 1740366695\nAND\n  toUnixTimestamp(timestamp) <= 1740377495\nGROUP BY\n  CASE\n    WHEN length(EXTRACT(instance, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN instance\n    ELSE '空'\n  END, CASE\n    WHEN length(EXTRACT(client_ip, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN client_ip\n    ELSE '空'\n  END, src_type, node_class, port, client_port\nLIMIT 10000;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_item_with_modifiers.sql",
    "content": "-- Origin SQL:\nSELECT c0 REPLACE(c0 AS c1) FROM t0;\nSELECT * REPLACE(i + 1 AS i) FROM t1;\nSELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from t2;\n\n\n-- Beautify SQL:\nSELECT\n  c0 REPLACE(c0 AS c1)\nFROM\n  t0;\nSELECT\n  * REPLACE(i + 1 AS i)\nFROM\n  t1;\nSELECT\n  * REPLACE(i + 1 AS i) EXCEPT(j) APPLY(sum)\nFROM\n  t2;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_json_type.sql",
    "content": "-- Origin SQL:\nSELECT a, a.b, a.b.c.d.e;\nSELECT JSON_TYPE('{\"a\": 1, \"b\": {\"c\": 2}}', '$.b');\nSELECT CAST(some, 'String') AS value;\nSELECT CAST(some.long, 'String') AS value;\nSELECT CAST(some.long.json, 'String') AS value;\nSELECT CAST(some.long.json.path, 'String') AS value;\n\n\n\n-- Beautify SQL:\nSELECT\n  a,\n  a.b,\n  a.b.c.d.e;\nSELECT\n  JSON_TYPE('{\"a\": 1, \"b\": {\"c\": 2}}', '$.b');\nSELECT\n  CAST(some, 'String') AS value;\nSELECT\n  CAST(some.long, 'String') AS value;\nSELECT\n  CAST(some.long.json, 'String') AS value;\nSELECT\n  CAST(some.long.json.path, 'String') AS value;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_keyword_alias_no_as.sql",
    "content": "-- Origin SQL:\nSELECT 'Joe' name FROM users\n\n-- Beautify SQL:\nSELECT\n  'Joe' AS name\nFROM\n  users;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_timestamp.sql",
    "content": "-- Origin SQL:\nSELECT Timestamp FROM events ORDER BY Timestamp;\n\n-- Beautify SQL:\nSELECT\n  Timestamp\nFROM\n  events\nORDER BY\n  Timestamp;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_with_fill_basic.sql",
    "content": "-- Origin SQL:\nSELECT n, source FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL;\n\n\n-- Beautify SQL:\nSELECT\n  n,\n  source\nFROM\n  (SELECT\n    toFloat32(number % 10) AS n,\n    'original' AS source\n  FROM\n    numbers(10)\n  WHERE\n    number % 3 = 1)\nORDER BY\n  n WITH FILL;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_with_fill_from_to.sql",
    "content": "-- Origin SQL:\nSELECT n, source FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;\n\n\n-- Beautify SQL:\nSELECT\n  n,\n  source\nFROM\n  (SELECT\n    toFloat32(number % 10) AS n,\n    'original' AS source\n  FROM\n    numbers(10)\n  WHERE\n    number % 3 = 1)\nORDER BY\n  n WITH FILL FROM 0 TO 5.51 STEP 0.5;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_with_fill_interpolate.sql",
    "content": "-- Origin SQL:\nSELECT n, source, inter FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5\nINTERPOLATE (inter AS inter + 1);\n\n\n-- Beautify SQL:\nSELECT\n  n,\n  source,\n  inter\nFROM\n  (SELECT\n    toFloat32(number % 10) AS n,\n    'original' AS source,\n    number AS inter\n  FROM\n    numbers(10)\n  WHERE\n    number % 3 = 1)\nORDER BY\n  n WITH FILL FROM 0 TO 5.51 STEP 0.5\n  INTERPOLATE (inter AS inter + 1);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_with_fill_interpolate_no_columns.sql",
    "content": "-- Origin SQL:\nSELECT n, value FROM (\n   SELECT toFloat32(number % 10) AS n, number AS value\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1\nINTERPOLATE;\n\n\n-- Beautify SQL:\nSELECT\n  n,\n  value\nFROM\n  (SELECT\n    toFloat32(number % 10) AS n,\n    number AS value\n  FROM\n    numbers(10)\n  WHERE\n    number % 3 = 1)\nORDER BY\n  n WITH FILL FROM 0 TO 10 STEP 1\n  INTERPOLATE;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_with_fill_staleness.sql",
    "content": "-- Origin SQL:\nSELECT number as key, 5 * number value, 'original' AS source\nFROM numbers(16)\nWHERE (number % 5) == 0\nORDER BY key WITH FILL STALENESS 11;\n\n\n-- Beautify SQL:\nSELECT\n  number AS key,\n  5 * number AS value,\n  'original' AS source\nFROM\n  numbers(16)\nWHERE\n  (number % 5) == 0\nORDER BY\n  key WITH FILL STALENESS 11;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_order_by_with_fill_step.sql",
    "content": "-- Origin SQL:\nSELECT date, value FROM (\n    SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value\n    FROM numbers(5)\n) ORDER BY date WITH FILL STEP INTERVAL 1 DAY;\n\n\n-- Beautify SQL:\nSELECT\n  date,\n  value\nFROM\n  (SELECT\n    toDate('2020-01-01') + INTERVAL number DAY AS date,\n    number AS value\n  FROM\n    numbers(5))\nORDER BY\n  date WITH FILL STEP INTERVAL 1 DAY;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple.sql",
    "content": "-- Origin SQL:\nSELECT\n    f0, coalesce(f1, f2) AS f3, row_number()\nOVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2')\nAND f3 NOT IN ('a', 'b', 'c')\n\n\nGROUP BY f0,   f1\n\nLimit 100, 10 By f0;\n\n-- Beautify SQL:\nSELECT\n  f0,\n  coalesce(f1, f2) AS f3,\n  row_number() OVER (PARTITION BY f0 ORDER BY\n    f1 ASC) AS rn\nFROM\n  test.events_local\nWHERE\n  (f0 IN ('foo', 'bar', 'test'))\nAND\n  (f1 = 'testing')\nAND\n  (f2 NOT LIKE 'testing2')\nAND\n  f3 NOT IN ('a', 'b', 'c')\nGROUP BY\n  f0, f1\nLIMIT 10 OFFSET 100 BY f0;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_field_alias.sql",
    "content": "-- Origin SQL:\nSELECT field0, field1 as x, field2 y from events;\n\n-- Beautify SQL:\nSELECT\n  field0,\n  field1 AS x,\n  field2 AS y\nFROM\n  events;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_bracket.sql",
    "content": "-- Origin SQL:\nSELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1[\"abc\"] as f2\n\n\n-- Beautify SQL:\nSELECT\n  arrayConcat([1, 2], [3, 4], [5, 6]) AS res,\n  f1[\"abc\"] AS f2;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_cte_with_column_aliases.sql",
    "content": "-- Origin SQL:\nWITH\n    test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales)\nSELECT\n    f1 AS new_f1,\n    f2 AS new_f2,\n    f3 AS new_f3\nFROM\n    test;\n\n\n-- Beautify SQL:\nWITH\n  test(f1, f2, f3) AS (SELECT\n    f4,\n    f5,\n    f6\n  FROM\n    sales)\nSELECT\n  f1 AS new_f1,\n  f2 AS new_f2,\n  f3 AS new_f3\nFROM\n  test;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_group_by_with_cube_totals.sql",
    "content": "-- Origin SQL:\nSELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;\n\n-- Beautify SQL:\nSELECT\n  a,\n  COUNT(b)\nFROM\n  group_by_all\nGROUP BY\n  CUBE(a)\n  WITH CUBE\n  WITH TOTALS\nORDER BY\n  a;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_is_not_null.sql",
    "content": "-- Origin SQL:\nSELECT f0,f1,f2,f3 as a0\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test'))\n  AND (f1 = 'testing')\n  AND f2 IS NULL\n  AND f3 IS NOT NULL\n\n-- Beautify SQL:\nSELECT\n  f0,\n  f1,\n  f2,\n  f3 AS a0\nFROM\n  test.events_local\nWHERE\n  (f0 IN ('foo', 'bar', 'test'))\nAND\n  (f1 = 'testing')\nAND\n  f2 IS NULL\nAND\n  f3 IS NOT NULL;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_is_null.sql",
    "content": "-- Origin SQL:\nSELECT f0,f1,f2,f3 as a0\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL\n\n-- Beautify SQL:\nSELECT\n  f0,\n  f1,\n  f2,\n  f3 AS a0\nFROM\n  test.events_local\nWHERE\n  (f0 IN ('foo', 'bar', 'test'))\nAND\n  (f1 = 'testing')\nAND\n  f2 IS NULL;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_limit.sql",
    "content": "-- Origin SQL:\nSELECT 1 LIMIT 1;\nSELECT 1 LIMIT 1 OFFSET 0;\nSELECT 1 OFFSET 0;\n\n\n-- Beautify SQL:\nSELECT\n  1\nLIMIT 1;\nSELECT\n  1\nLIMIT 1 OFFSET 0;\nSELECT\n  1\nOFFSET 0;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_top_clause.sql",
    "content": "-- Origin SQL:\nSELECT TOP 10 my_column FROM tableName;\n\n\n-- Beautify SQL:\nSELECT TOP 10\n  my_column\nFROM\n  tableName;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_simple_with_with_clause.sql",
    "content": "-- Origin SQL:\nWITH\n    cte1 AS (SELECT f1 FROM t1),\n    cte2 AS (SELECT f2 FROM t2)\nSELECT\n    cte1.f1,\n    cte2.f2,\n    t3.f3\nFROM\n    t3,cte1,cte2\n\n\n\n-- Beautify SQL:\nWITH\n  cte1 AS (SELECT\n    f1\n  FROM\n    t1),\n  cte2 AS (SELECT\n    f2\n  FROM\n    t2)\nSELECT\n  cte1.f1,\n  cte2.f2,\n  t3.f3\nFROM\n  t3,cte1,cte2;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_table_alias_without_keyword.sql",
    "content": "-- Origin SQL:\nSELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b\n\n-- Beautify SQL:\nSELECT\n  t1.Timestamp\nFROM\n  my_table AS t1\n  INNER JOIN\n    my_other_table AS t2 ON t1.a = t2.b;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_table_function_with_query.sql",
    "content": "-- Origin SQL:\nSELECT 1, (SELECT 70) AS `power`, number\nFROM\nnumbers(\n    plus(\n        ifNull((SELECT 1 AS bin_count, 1),\n        1)\n    )\n)\n\n-- Beautify SQL:\nSELECT\n  1,\n  (SELECT\n    70) AS `power`,\n  number\nFROM\n  numbers(plus(ifNull((SELECT\n    1 AS bin_count,\n    1), 1)));\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_when_condition.sql",
    "content": "-- Origin SQL:\nselect case when false then 'hello' else 'world' end;\n\n-- Beautify SQL:\nSELECT\n  CASE\n    WHEN false THEN 'hello'\n    ELSE 'world'\n  END;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_window_comprehensive.sql",
    "content": "-- Origin SQL:\n-- Comprehensive window spec coverage: ad-hoc specs, named windows, ROWS/RANGE frames\n-- multiple functions, multi-column PARTITION/ORDER, and expression-based specs.\nSELECT\n    -- Ad-hoc windows\n    sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)                                         AS running_total,\n    avg(x)\n        OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)                                    AS avg_range1,\n\n    -- Named window reuse (OVER w1)\n    row_number() OVER w1                                                                                              AS rn_w1,\n    rank() OVER w1                                                                                                    AS rank_w1,\n    sum(x) OVER w1                                                                                                    AS sum_w1,\n\n    -- Frame variants (incl. shorthand & RANGE)\n    sum(x) OVER (ROWS 10 PRECEDING)                                                                                   AS rows_10_preceding,\n    sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)                                                    AS rows_cur_to_unbounded_following,\n    sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING)                                                            AS rows_5p_3f,\n    sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW)                                                          AS range_10p_cur,\n    sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)                                                   AS range_unbounded_to_cur,\n\n    -- Ranking & navigation\n    row_number() OVER (PARTITION BY y ORDER BY x)                                                                     AS row_num,\n    rank() OVER (PARTITION BY y ORDER BY x)                                                                           AS rank_val,\n    dense_rank() OVER (PARTITION BY y ORDER BY x)                                                                     AS dense_rank_val,\n    first_value(x)\n                OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)             AS first_val,\n    last_value(x)\n               OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)              AS last_val,\n    lag(x, 1) OVER (PARTITION BY y ORDER BY x)                                                                        AS prev_x,\n    lead(x, 1) OVER (PARTITION BY y ORDER BY x)                                                                       AS next_x,\n    percent_rank() OVER (PARTITION BY y ORDER BY x)                                                                   AS pct_rank,\n\n    -- Named window reference via OVER w (no parentheses)\n    sum(x) OVER w                                                                                                     AS sum_over_w,\n    avg(x) OVER w                                                                                                     AS avg_over_w,\n    row_number() OVER w                                                                                               AS rn_over_w,\n\n    -- Multiple columns in PARTITION BY / ORDER BY\n    count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC)                                            AS cnt_multi,\n    sum(val)\n        OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)           AS total_multi,\n\n    -- Expressions in PARTITION/ORDER\n    sum(amount)\n        OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total,\n    avg(amount)\n        OVER (ORDER BY extract(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)                        AS hourly_avg\nFROM t\nWINDOW w AS (ORDER BY y),\n       w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),\n       w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW),\n       w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n\n\n-- Beautify SQL:\nSELECT\n  sum(x) OVER (ORDER BY\n    y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total,\n  avg(x) OVER (PARTITION BY z ORDER BY\n    y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1,\n  row_number() OVER w1 AS rn_w1,\n  rank() OVER w1 AS rank_w1,\n  sum(x) OVER w1 AS sum_w1,\n  sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding,\n  sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following,\n  sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f,\n  sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur,\n  sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur,\n  row_number() OVER (PARTITION BY y ORDER BY\n    x) AS row_num,\n  rank() OVER (PARTITION BY y ORDER BY\n    x) AS rank_val,\n  dense_rank() OVER (PARTITION BY y ORDER BY\n    x) AS dense_rank_val,\n  first_value(x) OVER (PARTITION BY y ORDER BY\n    x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val,\n  last_value(x) OVER (PARTITION BY y ORDER BY\n    x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val,\n  lag(x, 1) OVER (PARTITION BY y ORDER BY\n    x) AS prev_x,\n  lead(x, 1) OVER (PARTITION BY y ORDER BY\n    x) AS next_x,\n  percent_rank() OVER (PARTITION BY y ORDER BY\n    x) AS pct_rank,\n  sum(x) OVER w AS sum_over_w,\n  avg(x) OVER w AS avg_over_w,\n  row_number() OVER w AS rn_over_w,\n  count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY\n    col4,\n    col5 DESC) AS cnt_multi,\n  sum(val) OVER (PARTITION BY col1, col2 ORDER BY\n    col4,\n    col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi,\n  sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY\n    timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total,\n  avg(amount) OVER (ORDER BY\n    EXTRACT(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg\nFROM\n  t\nWINDOW w AS (ORDER BY\n  y), w1 AS (PARTITION BY y ORDER BY\n  x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY\n  x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY\n  x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_window_cte.sql",
    "content": "-- Origin SQL:\nWITH\n    monthly AS (\n        SELECT toStartOfMonth(date) AS month,\n               department,\n               avg(salary)          AS avg_salary\n        FROM salary_table\n        WHERE year = 2023\n        GROUP BY month, department\n    ),\n    ranked AS (\n        SELECT month,\n               department,\n               avg_salary,\n               row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank\n        FROM monthly\n    )\nSELECT month,\n       department,\n       avg_salary,\n       lag(avg_salary, 1, 0) OVER (\n           PARTITION BY department\n           ORDER BY month\n           ROWS BETWEEN 1 PRECEDING AND CURRENT ROW\n           ) AS prev_month_avg\nFROM ranked\nWHERE dept_rank <= 5\nORDER BY month, department;\n\n\n-- Beautify SQL:\nWITH\n  monthly AS (SELECT\n    toStartOfMonth(date) AS month,\n    department,\n    avg(salary) AS avg_salary\n  FROM\n    salary_table\n  WHERE\n    year = 2023\n  GROUP BY\n    month, department),\n  ranked AS (SELECT\n    month,\n    department,\n    avg_salary,\n    row_number() OVER (PARTITION BY department ORDER BY\n      avg_salary DESC) AS dept_rank\n  FROM\n    monthly)\nSELECT\n  month,\n  department,\n  avg_salary,\n  lag(avg_salary, 1, 0) OVER (PARTITION BY department ORDER BY\n    month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_month_avg\nFROM\n  ranked\nWHERE\n  dept_rank <= 5\nORDER BY\n  month,\n  department;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_window_keyword_name_in_parens.sql",
    "content": "-- Origin SQL:\nSELECT sum(x) OVER (order) AS sum_over_order\nFROM t\nWINDOW order AS (PARTITION BY team ORDER BY ts);\n\n\n-- Beautify SQL:\nSELECT\n  sum(x) OVER (order) AS sum_over_order\nFROM\n  t\nWINDOW order AS (PARTITION BY team ORDER BY\n  ts);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_window_named_in_parens.sql",
    "content": "-- Origin SQL:\nSELECT sum(x) OVER (w) AS sum_over_w\nFROM t\nWINDOW w AS (PARTITION BY y ORDER BY x);\n\n\n-- Beautify SQL:\nSELECT\n  sum(x) OVER (w) AS sum_over_w\nFROM\n  t\nWINDOW w AS (PARTITION BY y ORDER BY\n  x);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_window_named_reference_extensions.sql",
    "content": "-- Origin SQL:\nSELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,\n       avg(x) OVER (w2)                                                      AS avg_over_w2\nFROM t\nWINDOW w1 AS (PARTITION BY team),\n       w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n\n\n-- Beautify SQL:\nSELECT\n  sum(x) OVER (w1 ORDER BY\n    ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,\n  avg(x) OVER (w2) AS avg_over_w2\nFROM\n  t\nWINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY\n  ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_window_params.sql",
    "content": "-- Origin SQL:\n-- Parameters in WHERE and in window frames (UInt32 & String; both spacing styles; shorthand frame)\nSELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start:UInt32} PRECEDING AND CURRENT ROW)                           AS total1,\n       avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end:UInt32} FOLLOWING)                             AS avg1,\n       count(*) OVER (ORDER BY y RANGE BETWEEN {range_start:UInt32} PRECEDING AND {range_end:UInt32} FOLLOWING) AS cnt1,\n       sum(x) OVER (ROWS {window_size :UInt32} PRECEDING)                                                       AS rows_shorthand\nFROM t\nWHERE category = {category :String}\n  AND type = {type:String};\n\n\n-- Beautify SQL:\nSELECT\n  sum(x) OVER (ORDER BY\n    y ROWS BETWEEN {start: UInt32} PRECEDING AND CURRENT ROW) AS total1,\n  avg(x) OVER (ORDER BY\n    y ROWS BETWEEN CURRENT ROW AND {end: UInt32} FOLLOWING) AS avg1,\n  count(*) OVER (ORDER BY\n    y RANGE BETWEEN {range_start: UInt32} PRECEDING AND {range_end: UInt32} FOLLOWING) AS cnt1,\n  sum(x) OVER (ROWS {window_size: UInt32} PRECEDING) AS rows_shorthand\nFROM\n  t\nWHERE\n  category = {category: String}\nAND\n  type = {type: String};\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_distinct.sql",
    "content": "-- Origin SQL:\nSELECT count(DISTINCT(RECORD_ID)) FROM RECORD_TABLE\n\n-- Beautify SQL:\nSELECT\n  count(DISTINCT (RECORD_ID))\nFROM\n  RECORD_TABLE;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_distinct_keyword.sql",
    "content": "-- Origin SQL:\nSELECT DISTINCT record_id FROM records \n\n-- Beautify SQL:\nSELECT DISTINCT\n  record_id\nFROM\n  records;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_distinct_on_dotted_columns.sql",
    "content": "-- Origin SQL:\nSELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table t\n\n-- Beautify SQL:\nSELECT DISTINCT ON (t.id, t.name)\n  t.id,\n  t.name,\n  t.value\nFROM\n  test_table AS t;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_distinct_on_keyword.sql",
    "content": "-- Origin SQL:\nSELECT DISTINCT ON(album,artist) record_id FROM records\n\n-- Beautify SQL:\nSELECT DISTINCT ON (album, artist)\n  record_id\nFROM\n  records;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_group_by.sql",
    "content": "-- Origin SQL:\nSELECT\n    datacenter,\n    distro,\n    SUM (quantity) AS qty\nFROM\n    servers\nGROUP BY\n    GROUPING SETS(\n    (datacenter,distro),\n    (datacenter),\n    (distro),\n    ()\n);\n\nSELECT\n    datacenter,\n    distro,\n    SUM (quantity) AS qty\nFROM\n    servers\nGROUP BY ALL;\n\n-- Beautify SQL:\nSELECT\n  datacenter,\n  distro,\n  SUM(quantity) AS qty\nFROM\n  servers\nGROUP BY\n  GROUPING SETS((datacenter, distro), (datacenter), (distro), ());\nSELECT\n  datacenter,\n  distro,\n  SUM(quantity) AS qty\nFROM\n  servers\nGROUP BY\n  ALL;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_join_only.sql",
    "content": "-- Origin SQL:\nSELECT * FROM \"t1\" JOIN \"t2\" ON true\n\n\n-- Beautify SQL:\nSELECT\n  *\nFROM\n  \"t1\"\n  JOIN\n    \"t2\" ON true;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_keyword_in_group_by.sql",
    "content": "-- Origin SQL:\nSELECT\n    toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval,\n    column_name\nFROM table\nWHERE true\nGROUP BY (interval, column_name)\nORDER BY (interval AS i, column_name) ASC\n\n-- Beautify SQL:\nSELECT\n  toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval,\n  column_name\nFROM\n  table\nWHERE\n  true\nGROUP BY\n  (interval, column_name)\nORDER BY\n  (interval AS i, column_name) ASC;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_keyword_placeholder.sql",
    "content": "-- Origin SQL:\nSELECT {name :String};\nSELECT toString({name :String});\n\n\n\n-- Beautify SQL:\nSELECT\n  {name: String};\nSELECT\n  toString({name: String});\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_left_join.sql",
    "content": "-- Origin SQL:\nWITH\n    t1 AS\n        (\n            SELECT 1 AS value\n    ),\n    t2 AS\n       (\nSELECT 2 AS value\n    )\nSELECT *\nFROM t1\n         LEFT JOIN t2 ON true\n\n-- Beautify SQL:\nWITH\n  t1 AS (SELECT\n    1 AS value),\n  t2 AS (SELECT\n    2 AS value)\nSELECT\n  *\nFROM\n  t1\n  LEFT JOIN\n    t2 ON true;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_literal_table_name.sql",
    "content": "-- Origin SQL:\nselect table_name from \"information_schema\".\"tables\" limit 1;\n\n\n-- Beautify SQL:\nSELECT\n  table_name\nFROM\n  \"information_schema\".\"tables\"\nLIMIT 1;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_array_and_inner_join.sql",
    "content": "-- Origin SQL:\nSELECT\n    JSONExtractString(t3.props, 'value') AS value\nFROM t1\n    ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1\n    INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id')\n    ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2\n    INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id')\nWHERE value != '';\n\n-- Beautify SQL:\nSELECT\n  JSONExtractString(t3.props, 'value') AS value\nFROM\n  t1\n  ARRAY JOIN\n    JSONExtractArrayRaw(t1.props, 'arr1') AS a1\n  INNER JOIN\n    t2 ON t2.id = JSONExtractString(a1, 'id')\n  ARRAY JOIN\n    JSONExtractArrayRaw(t2.props, 'arr2') AS a2\n  INNER JOIN\n    t3 ON t3.id = JSONExtractString(a2, 'id')\nWHERE\n  value != '';\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_array_join.sql",
    "content": "-- Origin SQL:\nSELECT\n    v,\n    j\nFROM t1\n    ARRAY JOIN JSONExtractArrayRaw(a) AS j\n    ARRAY JOIN array(\n    JSONExtractString(j, 'x'),\n    JSONExtractString(j, 'y')\n) AS v;\n\n-- Beautify SQL:\nSELECT\n  v,\n  j\nFROM\n  t1\n  ARRAY JOIN\n    JSONExtractArrayRaw(a) AS j\n  ARRAY JOIN\n    array(JSONExtractString(j, 'x'), JSONExtractString(j, 'y')) AS v;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_except.sql",
    "content": "-- Origin SQL:\nSELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9)\n\n-- Beautify SQL:\nSELECT\n  number\nFROM\n  numbers(1, 10)\nEXCEPT\nSELECT\n  number\nFROM\n  numbers(3, 6)\nEXCEPT\nSELECT\n  number\nFROM\n  numbers(8, 9);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_join.sql",
    "content": "-- Origin SQL:\nwith t1 as (\n    select 'value1' as value\n    ), t2 as (\nselect 'value2' as value\n    ), t3 as (\nselect 'value3' as value\n    )\nselect\n    t1.value as value1,\n    t2.value as value2,\n    t3.value as value3\nfrom\n    t1\n        join t2 on true\n        join t3\n        join t4 on true\n        join t5\n\n\n-- Beautify SQL:\nWITH\n  t1 AS (SELECT\n    'value1' AS value),\n  t2 AS (SELECT\n    'value2' AS value),\n  t3 AS (SELECT\n    'value3' AS value)\nSELECT\n  t1.value AS value1,\n  t2.value AS value2,\n  t3.value AS value3\nFROM\n  t1\n  JOIN\n    t2 ON true\n  JOIN\n    t3\n  JOIN\n    t4 ON true\n  JOIN\n    t5;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_line_comment.sql",
    "content": "-- Origin SQL:\nselect\n    -- first line\n    -- second line\n    *\nfrom\n    t0\n\n-- Beautify SQL:\nSELECT\n  *\nFROM\n  t0;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_union.sql",
    "content": "-- Origin SQL:\nSELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3\n\n\n-- Beautify SQL:\nSELECT\n  1 AS v1\nUNION ALL\nSELECT\n  2 AS v2\nUNION ALL\nSELECT\n  3 AS v3;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_multi_union_distinct.sql",
    "content": "-- Origin SQL:\nSELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3\n\n-- Beautify SQL:\nSELECT\n  1 AS v1\nUNION DISTINCT\nSELECT\n  2 AS v2\nUNION DISTINCT\nSELECT\n  3 AS v3;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_number_field.sql",
    "content": "-- Origin SQL:\nSELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m as bar\n\n-- Beautify SQL:\nSELECT\n  foo,\n  bar.1,\n  foo.2\nFROM\n  foo\n  ARRAY JOIN\n    m AS bar;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_placeholder.sql",
    "content": "-- Origin SQL:\nSELECT * FROM t0 WHERE id = ?;\n\n-- Beautify SQL:\nSELECT\n  *\nFROM\n  t0\nWHERE\n  id = ?;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_query_parameter.sql",
    "content": "-- Origin SQL:\nSET param_a = 13;\nSET param_b = 'str';\nSET param_c = '2022-08-04 18:30:53';\nSET param_d = {'10': [11, 12], '13': [14, 15]};\n\nSELECT\n    {a: UInt32},\n    {b: String},\n    {c: DateTime},\n    {d: Map(String, Array(UInt8))};\n\nSELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String};\n\n\n-- Beautify SQL:\nSET param_a=13;\nSET param_b='str';\nSET param_c='2022-08-04 18:30:53';\nSET param_d={'10': [11, 12], '13': [14, 15]};\nSELECT\n  {a: UInt32},\n  {b: String},\n  {c: DateTime},\n  {d: Map(String, Array(UInt8))};\nSELECT\n  *\nFROM\n  clickhouse\nWHERE\n  tenant_id = {tenant_id: String};\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_settings_additional_table_filters.sql",
    "content": "-- Origin SQL:\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'};\n\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \\'test\\''};\n\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''};\n\nSELECT * FROM test_table\nSETTINGS additional_table_filters={'test_table': 'id IN (\\'a\\', \\'b\\') AND status = \\'active\\''}\nFORMAT JSON;\n\nSELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) f\nANY LEFT JOIN (SELECT x, y FROM table_1) s ON f.number = s.x\nSETTINGS additional_table_filters={'system.numbers':'number != 3', 'table_1':'x != 2'};\n\n\n-- Beautify SQL:\nSELECT\n  *\nFROM\n  test_table\nSETTINGS\n  additional_table_filters={'test_table': 'status = 1'};\nSELECT\n  *\nFROM\n  test_table\nSETTINGS\n  additional_table_filters={'test_table': 'value = \\'test\\''};\nSELECT\n  *\nFROM\n  test_table\nSETTINGS\n  additional_table_filters={'test_table': 'value = ''test'''};\nSELECT\n  *\nFROM\n  test_table\nSETTINGS\n  additional_table_filters={'test_table': 'id IN (\\'a\\', \\'b\\') AND status = \\'active\\''}\nFORMAT JSON;\nSELECT\n  number,\n  x,\n  y\nFROM\n  (SELECT\n    number\n  FROM\n    system.numbers\n  LIMIT 5) AS f\n  ANY LEFT JOIN\n    (SELECT\n      x,\n      y\n    FROM\n      table_1) AS s ON f.number = s.x\nSETTINGS\n  additional_table_filters={'system.numbers': 'number != 3', 'table_1': 'x != 2'};\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_single_quote_table.sql",
    "content": "-- Origin SQL:\nSELECT * FROM 'test_table'\n\n\n-- Beautify SQL:\nSELECT\n  *\nFROM\n  'test_table';\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_string_expr.sql",
    "content": "-- Origin SQL:\nWITH \"abc\" AS (SELECT 1 AS a) SELECT * FROM \"abc\"\n\n\n-- Beautify SQL:\nWITH\n  \"abc\" AS (SELECT\n    1 AS a)\nSELECT\n  *\nFROM\n  \"abc\";\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_union_distinct.sql",
    "content": "-- Origin SQL:\nSELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON\n\n-- Beautify SQL:\nSELECT\n  replica_name\nFROM\n  system.ha_replicas\nUNION DISTINCT\nSELECT\n  replica_name\nFROM\n  system.ha_unique_replicas\nFORMAT JSON;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_variable.sql",
    "content": "-- Origin SQL:\nWITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc\n\n-- Beautify SQL:\nWITH\n  $abc AS (SELECT\n    1 AS a)\nSELECT\n  *\nFROM\n  $abc;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_with_window_function.sql",
    "content": "-- Origin SQL:\nSELECT aggregation_target AS aggregation_target,\n    timestamp AS timestamp,\n    step_0 AS step_0,\n    latest_0 AS latest_0,\n    step_1 AS step_1,\n    latest_1 AS latest_1,\n    step_2 AS step_2,\n    min(latest_2) OVER (PARTITION BY aggregation_target\n    ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2,\n    min(latest_1) OVER w AS latest_1\nFROM t0\nWINDOW w AS (PARTITION BY aggregation_target\n    ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING);\n\n-- Beautify SQL:\nSELECT\n  aggregation_target AS aggregation_target,\n  timestamp AS timestamp,\n  step_0 AS step_0,\n  latest_0 AS latest_0,\n  step_1 AS step_1,\n  latest_1 AS latest_1,\n  step_2 AS step_2,\n  min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY\n    timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2,\n  min(latest_1) OVER w AS latest_1\nFROM\n  t0\nWINDOW w AS (PARTITION BY aggregation_target ORDER BY\n  timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING);\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/select_without_from_where.sql",
    "content": "-- Origin SQL:\nSELECT 1 WHERE 1 = 1;\nSELECT {p :UInt8} WHERE {p :UInt8} = 1;\n\n\n\n-- Beautify SQL:\nSELECT\n  1\nWHERE\n  1 = 1;\nSELECT\n  {p: UInt8}\nWHERE\n  {p: UInt8} = 1;\n"
  },
  {
    "path": "parser/testdata/query/format/beautify/set_simple.sql",
    "content": "-- Origin SQL:\nSET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage\n\n-- Beautify SQL:\nSET max_threads=1, max_insert_threads=0, max_block_size=8192, min_insert_block_size_rows=8192, min_insert_block_size_bytes=1048576;\n"
  },
  {
    "path": "parser/testdata/query/format/create_window_view.sql",
    "content": "-- Origin SQL:\nCREATE OR REPLACE VIEW asdf AS\nSELECT id,\n       price * 1.5 AS computed_value,\n       row_number() OVER (\n           PARTITION BY category\n           ORDER BY created_at\n           RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW\n           )       AS rn\nFROM source_table\nWHERE date >= '2023-01-01';\n\n\n-- Format SQL:\nCREATE OR REPLACE VIEW asdf AS SELECT id, price * 1.5 AS computed_value, row_number() OVER (PARTITION BY category ORDER BY created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW) AS rn FROM source_table WHERE date >= '2023-01-01';\n"
  },
  {
    "path": "parser/testdata/query/format/query_with_expr_compare.sql",
    "content": "-- Origin SQL:\nSELECT date, path, splitByChar('/', path)[2] AS path_b\nFROM(\n    SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date\n    )\nWHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30'\n  AND splitByChar('/', path)[1] = 'pathA'\n\n-- Format SQL:\nSELECT date, path, splitByChar('/', path)[2] AS path_b FROM (SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date) WHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30' AND splitByChar('/', path)[1] = 'pathA';\n"
  },
  {
    "path": "parser/testdata/query/format/select_case_multiple_when.sql",
    "content": "-- Origin SQL:\nSELECT\n    *,\n    CASE\n        WHEN col2 = 'value1' THEN 'when1'\n        WHEN col3 = 'value2' THEN 'when2'\n        ELSE 'else'\n    END as check_result\nFROM table_name\nWHERE col1 = '123456789'\n\n\n-- Format SQL:\nSELECT *, CASE WHEN col2 = 'value1' THEN 'when1' WHEN col3 = 'value2' THEN 'when2' ELSE 'else' END AS check_result FROM table_name WHERE col1 = '123456789';\n"
  },
  {
    "path": "parser/testdata/query/format/select_case_when_exists.sql",
    "content": "-- Origin SQL:\nSELECT\n    *,\n    CASE\n        WHEN EXISTS(SELECT 1\n    FROM table_name\n    WHERE col1 = '999999999')\n        THEN 'then'\n        ELSE 'else'\n    END as check_result\nFROM table_name\nWHERE col1 = '123456789'\n\n\n-- Format SQL:\nSELECT *, CASE WHEN EXISTS(SELECT 1 FROM table_name WHERE col1 = '999999999') THEN 'then' ELSE 'else' END AS check_result FROM table_name WHERE col1 = '123456789';\n"
  },
  {
    "path": "parser/testdata/query/format/select_cast.sql",
    "content": "-- Origin SQL:\nselect cast(1 as Float64) as value;\nselect cast(1, 'Float64') as value;\nselect (1 as Float64) as value;\nselect 1::Float64 as value;\n\n-- Format SQL:\nSELECT CAST(1 AS Float64) AS value;\nSELECT CAST(1, 'Float64') AS value;\nSELECT (1 AS Float64) AS value;\nSELECT 1::Float64 AS value;\n"
  },
  {
    "path": "parser/testdata/query/format/select_column_alias_string.sql",
    "content": "-- Origin SQL:\nSELECT 'abc' as \"value2\";\n\nSELECT $abc, a$$bc, abc$$;\n\n\n-- Format SQL:\nSELECT 'abc' AS \"value2\";\nSELECT $abc, a$$bc, abc$$;\n"
  },
  {
    "path": "parser/testdata/query/format/select_concat_expr.sql",
    "content": "-- Origin SQL:\nSELECT 'a' || 'b';\nSELECT 'a' || 'b' || 'c';\nSELECT 'a' || 'b' || 'c' + 5;\n\n\n-- Format SQL:\nSELECT 'a' || 'b';\nSELECT 'a' || 'b' || 'c';\nSELECT 'a' || 'b' || 'c' + 5;\n"
  },
  {
    "path": "parser/testdata/query/format/select_expr.sql",
    "content": "-- Origin SQL:\nSELECT 1+1\n\n-- Format SQL:\nSELECT 1 + 1;\n"
  },
  {
    "path": "parser/testdata/query/format/select_extract_with_regex.sql",
    "content": "-- Origin SQL:\nSELECT\n  COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT\nFROM\n  test.table\nWHERE\n  app_id = 999118646\n  AND toUnixTimestamp(timestamp) >= 1740366695\n  AND toUnixTimestamp(timestamp) <= 1740377495\nGROUP BY\n  CASE\n    WHEN length(extract(instance, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN instance\n    ELSE '空'\n  END,\n  CASE\n    WHEN length(extract(client_ip, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN client_ip\n    ELSE '空'\n  END,\n  src_type,\n  node_class,\n  port,\n  client_port\nLIMIT 10000\n\n\n-- Format SQL:\nSELECT COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT FROM test.table WHERE app_id = 999118646 AND toUnixTimestamp(timestamp) >= 1740366695 AND toUnixTimestamp(timestamp) <= 1740377495 GROUP BY CASE WHEN length(EXTRACT(instance, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN instance ELSE '空' END, CASE WHEN length(EXTRACT(client_ip, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN client_ip ELSE '空' END, src_type, node_class, port, client_port LIMIT 10000;\n"
  },
  {
    "path": "parser/testdata/query/format/select_item_with_modifiers.sql",
    "content": "-- Origin SQL:\nSELECT c0 REPLACE(c0 AS c1) FROM t0;\nSELECT * REPLACE(i + 1 AS i) FROM t1;\nSELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from t2;\n\n\n-- Format SQL:\nSELECT c0 REPLACE(c0 AS c1) FROM t0;\nSELECT * REPLACE(i + 1 AS i) FROM t1;\nSELECT * REPLACE(i + 1 AS i) EXCEPT(j) APPLY(sum) FROM t2;\n"
  },
  {
    "path": "parser/testdata/query/format/select_json_type.sql",
    "content": "-- Origin SQL:\nSELECT a, a.b, a.b.c.d.e;\nSELECT JSON_TYPE('{\"a\": 1, \"b\": {\"c\": 2}}', '$.b');\nSELECT CAST(some, 'String') AS value;\nSELECT CAST(some.long, 'String') AS value;\nSELECT CAST(some.long.json, 'String') AS value;\nSELECT CAST(some.long.json.path, 'String') AS value;\n\n\n\n-- Format SQL:\nSELECT a, a.b, a.b.c.d.e;\nSELECT JSON_TYPE('{\"a\": 1, \"b\": {\"c\": 2}}', '$.b');\nSELECT CAST(some, 'String') AS value;\nSELECT CAST(some.long, 'String') AS value;\nSELECT CAST(some.long.json, 'String') AS value;\nSELECT CAST(some.long.json.path, 'String') AS value;\n"
  },
  {
    "path": "parser/testdata/query/format/select_keyword_alias_no_as.sql",
    "content": "-- Origin SQL:\nSELECT 'Joe' name FROM users\n\n-- Format SQL:\nSELECT 'Joe' AS name FROM users;\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_timestamp.sql",
    "content": "-- Origin SQL:\nSELECT Timestamp FROM events ORDER BY Timestamp;\n\n-- Format SQL:\nSELECT Timestamp FROM events ORDER BY Timestamp;\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_with_fill_basic.sql",
    "content": "-- Origin SQL:\nSELECT n, source FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL;\n\n\n-- Format SQL:\nSELECT n, source FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL;\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_with_fill_from_to.sql",
    "content": "-- Origin SQL:\nSELECT n, source FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;\n\n\n-- Format SQL:\nSELECT n, source FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_with_fill_interpolate.sql",
    "content": "-- Origin SQL:\nSELECT n, source, inter FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5\nINTERPOLATE (inter AS inter + 1);\n\n\n-- Format SQL:\nSELECT n, source, inter FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1);\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_with_fill_interpolate_no_columns.sql",
    "content": "-- Origin SQL:\nSELECT n, value FROM (\n   SELECT toFloat32(number % 10) AS n, number AS value\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1\nINTERPOLATE;\n\n\n-- Format SQL:\nSELECT n, value FROM (SELECT toFloat32(number % 10) AS n, number AS value FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1 INTERPOLATE;\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_with_fill_staleness.sql",
    "content": "-- Origin SQL:\nSELECT number as key, 5 * number value, 'original' AS source\nFROM numbers(16)\nWHERE (number % 5) == 0\nORDER BY key WITH FILL STALENESS 11;\n\n\n-- Format SQL:\nSELECT number AS key, 5 * number AS value, 'original' AS source FROM numbers(16) WHERE (number % 5) == 0 ORDER BY key WITH FILL STALENESS 11;\n"
  },
  {
    "path": "parser/testdata/query/format/select_order_by_with_fill_step.sql",
    "content": "-- Origin SQL:\nSELECT date, value FROM (\n    SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value\n    FROM numbers(5)\n) ORDER BY date WITH FILL STEP INTERVAL 1 DAY;\n\n\n-- Format SQL:\nSELECT date, value FROM (SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value FROM numbers(5)) ORDER BY date WITH FILL STEP INTERVAL 1 DAY;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple.sql",
    "content": "-- Origin SQL:\nSELECT\n    f0, coalesce(f1, f2) AS f3, row_number()\nOVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2')\nAND f3 NOT IN ('a', 'b', 'c')\n\n\nGROUP BY f0,   f1\n\nLimit 100, 10 By f0;\n\n-- Format SQL:\nSELECT f0, coalesce(f1, f2) AS f3, row_number() OVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c') GROUP BY f0, f1 LIMIT 10 OFFSET 100 BY f0;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_field_alias.sql",
    "content": "-- Origin SQL:\nSELECT field0, field1 as x, field2 y from events;\n\n-- Format SQL:\nSELECT field0, field1 AS x, field2 AS y FROM events;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_bracket.sql",
    "content": "-- Origin SQL:\nSELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1[\"abc\"] as f2\n\n\n-- Format SQL:\nSELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1[\"abc\"] AS f2;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_cte_with_column_aliases.sql",
    "content": "-- Origin SQL:\nWITH\n    test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales)\nSELECT\n    f1 AS new_f1,\n    f2 AS new_f2,\n    f3 AS new_f3\nFROM\n    test;\n\n\n-- Format SQL:\nWITH test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales) SELECT f1 AS new_f1, f2 AS new_f2, f3 AS new_f3 FROM test;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_group_by_with_cube_totals.sql",
    "content": "-- Origin SQL:\nSELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;\n\n-- Format SQL:\nSELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_is_not_null.sql",
    "content": "-- Origin SQL:\nSELECT f0,f1,f2,f3 as a0\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test'))\n  AND (f1 = 'testing')\n  AND f2 IS NULL\n  AND f3 IS NOT NULL\n\n-- Format SQL:\nSELECT f0, f1, f2, f3 AS a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL AND f3 IS NOT NULL;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_is_null.sql",
    "content": "-- Origin SQL:\nSELECT f0,f1,f2,f3 as a0\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL\n\n-- Format SQL:\nSELECT f0, f1, f2, f3 AS a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_limit.sql",
    "content": "-- Origin SQL:\nSELECT 1 LIMIT 1;\nSELECT 1 LIMIT 1 OFFSET 0;\nSELECT 1 OFFSET 0;\n\n\n-- Format SQL:\nSELECT 1 LIMIT 1;\nSELECT 1 LIMIT 1 OFFSET 0;\nSELECT 1 OFFSET 0;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_top_clause.sql",
    "content": "-- Origin SQL:\nSELECT TOP 10 my_column FROM tableName;\n\n\n-- Format SQL:\nSELECT TOP 10 my_column FROM tableName;\n"
  },
  {
    "path": "parser/testdata/query/format/select_simple_with_with_clause.sql",
    "content": "-- Origin SQL:\nWITH\n    cte1 AS (SELECT f1 FROM t1),\n    cte2 AS (SELECT f2 FROM t2)\nSELECT\n    cte1.f1,\n    cte2.f2,\n    t3.f3\nFROM\n    t3,cte1,cte2\n\n\n\n-- Format SQL:\nWITH cte1 AS (SELECT f1 FROM t1), cte2 AS (SELECT f2 FROM t2) SELECT cte1.f1, cte2.f2, t3.f3 FROM t3,cte1,cte2;\n"
  },
  {
    "path": "parser/testdata/query/format/select_table_alias_without_keyword.sql",
    "content": "-- Origin SQL:\nSELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b\n\n-- Format SQL:\nSELECT t1.Timestamp FROM my_table AS t1 INNER JOIN my_other_table AS t2 ON t1.a = t2.b;\n"
  },
  {
    "path": "parser/testdata/query/format/select_table_function_with_query.sql",
    "content": "-- Origin SQL:\nSELECT 1, (SELECT 70) AS `power`, number\nFROM\nnumbers(\n    plus(\n        ifNull((SELECT 1 AS bin_count, 1),\n        1)\n    )\n)\n\n-- Format SQL:\nSELECT 1, (SELECT 70) AS `power`, number FROM numbers(plus(ifNull((SELECT 1 AS bin_count, 1), 1)));\n"
  },
  {
    "path": "parser/testdata/query/format/select_when_condition.sql",
    "content": "-- Origin SQL:\nselect case when false then 'hello' else 'world' end;\n\n-- Format SQL:\nSELECT CASE WHEN false THEN 'hello' ELSE 'world' END;\n"
  },
  {
    "path": "parser/testdata/query/format/select_window_comprehensive.sql",
    "content": "-- Origin SQL:\n-- Comprehensive window spec coverage: ad-hoc specs, named windows, ROWS/RANGE frames\n-- multiple functions, multi-column PARTITION/ORDER, and expression-based specs.\nSELECT\n    -- Ad-hoc windows\n    sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)                                         AS running_total,\n    avg(x)\n        OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)                                    AS avg_range1,\n\n    -- Named window reuse (OVER w1)\n    row_number() OVER w1                                                                                              AS rn_w1,\n    rank() OVER w1                                                                                                    AS rank_w1,\n    sum(x) OVER w1                                                                                                    AS sum_w1,\n\n    -- Frame variants (incl. shorthand & RANGE)\n    sum(x) OVER (ROWS 10 PRECEDING)                                                                                   AS rows_10_preceding,\n    sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)                                                    AS rows_cur_to_unbounded_following,\n    sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING)                                                            AS rows_5p_3f,\n    sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW)                                                          AS range_10p_cur,\n    sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)                                                   AS range_unbounded_to_cur,\n\n    -- Ranking & navigation\n    row_number() OVER (PARTITION BY y ORDER BY x)                                                                     AS row_num,\n    rank() OVER (PARTITION BY y ORDER BY x)                                                                           AS rank_val,\n    dense_rank() OVER (PARTITION BY y ORDER BY x)                                                                     AS dense_rank_val,\n    first_value(x)\n                OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)             AS first_val,\n    last_value(x)\n               OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)              AS last_val,\n    lag(x, 1) OVER (PARTITION BY y ORDER BY x)                                                                        AS prev_x,\n    lead(x, 1) OVER (PARTITION BY y ORDER BY x)                                                                       AS next_x,\n    percent_rank() OVER (PARTITION BY y ORDER BY x)                                                                   AS pct_rank,\n\n    -- Named window reference via OVER w (no parentheses)\n    sum(x) OVER w                                                                                                     AS sum_over_w,\n    avg(x) OVER w                                                                                                     AS avg_over_w,\n    row_number() OVER w                                                                                               AS rn_over_w,\n\n    -- Multiple columns in PARTITION BY / ORDER BY\n    count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC)                                            AS cnt_multi,\n    sum(val)\n        OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)           AS total_multi,\n\n    -- Expressions in PARTITION/ORDER\n    sum(amount)\n        OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total,\n    avg(amount)\n        OVER (ORDER BY extract(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)                        AS hourly_avg\nFROM t\nWINDOW w AS (ORDER BY y),\n       w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),\n       w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW),\n       w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n\n\n-- Format SQL:\nSELECT sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total, avg(x) OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1, row_number() OVER w1 AS rn_w1, rank() OVER w1 AS rank_w1, sum(x) OVER w1 AS sum_w1, sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following, sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f, sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur, sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur, row_number() OVER (PARTITION BY y ORDER BY x) AS row_num, rank() OVER (PARTITION BY y ORDER BY x) AS rank_val, dense_rank() OVER (PARTITION BY y ORDER BY x) AS dense_rank_val, first_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val, last_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val, lag(x, 1) OVER (PARTITION BY y ORDER BY x) AS prev_x, lead(x, 1) OVER (PARTITION BY y ORDER BY x) AS next_x, percent_rank() OVER (PARTITION BY y ORDER BY x) AS pct_rank, sum(x) OVER w AS sum_over_w, avg(x) OVER w AS avg_over_w, row_number() OVER w AS rn_over_w, count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC) AS cnt_multi, sum(val) OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi, sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total, avg(amount) OVER (ORDER BY EXTRACT(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg FROM t WINDOW w AS (ORDER BY y), w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n"
  },
  {
    "path": "parser/testdata/query/format/select_window_cte.sql",
    "content": "-- Origin SQL:\nWITH\n    monthly AS (\n        SELECT toStartOfMonth(date) AS month,\n               department,\n               avg(salary)          AS avg_salary\n        FROM salary_table\n        WHERE year = 2023\n        GROUP BY month, department\n    ),\n    ranked AS (\n        SELECT month,\n               department,\n               avg_salary,\n               row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank\n        FROM monthly\n    )\nSELECT month,\n       department,\n       avg_salary,\n       lag(avg_salary, 1, 0) OVER (\n           PARTITION BY department\n           ORDER BY month\n           ROWS BETWEEN 1 PRECEDING AND CURRENT ROW\n           ) AS prev_month_avg\nFROM ranked\nWHERE dept_rank <= 5\nORDER BY month, department;\n\n\n-- Format SQL:\nWITH monthly AS (SELECT toStartOfMonth(date) AS month, department, avg(salary) AS avg_salary FROM salary_table WHERE year = 2023 GROUP BY month, department), ranked AS (SELECT month, department, avg_salary, row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank FROM monthly) SELECT month, department, avg_salary, lag(avg_salary, 1, 0) OVER (PARTITION BY department ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_month_avg FROM ranked WHERE dept_rank <= 5 ORDER BY month, department;\n"
  },
  {
    "path": "parser/testdata/query/format/select_window_keyword_name_in_parens.sql",
    "content": "-- Origin SQL:\nSELECT sum(x) OVER (order) AS sum_over_order\nFROM t\nWINDOW order AS (PARTITION BY team ORDER BY ts);\n\n\n-- Format SQL:\nSELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts);\n"
  },
  {
    "path": "parser/testdata/query/format/select_window_named_in_parens.sql",
    "content": "-- Origin SQL:\nSELECT sum(x) OVER (w) AS sum_over_w\nFROM t\nWINDOW w AS (PARTITION BY y ORDER BY x);\n\n\n-- Format SQL:\nSELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x);\n"
  },
  {
    "path": "parser/testdata/query/format/select_window_named_reference_extensions.sql",
    "content": "-- Origin SQL:\nSELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,\n       avg(x) OVER (w2)                                                      AS avg_over_w2\nFROM t\nWINDOW w1 AS (PARTITION BY team),\n       w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n\n\n-- Format SQL:\nSELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n"
  },
  {
    "path": "parser/testdata/query/format/select_window_params.sql",
    "content": "-- Origin SQL:\n-- Parameters in WHERE and in window frames (UInt32 & String; both spacing styles; shorthand frame)\nSELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start:UInt32} PRECEDING AND CURRENT ROW)                           AS total1,\n       avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end:UInt32} FOLLOWING)                             AS avg1,\n       count(*) OVER (ORDER BY y RANGE BETWEEN {range_start:UInt32} PRECEDING AND {range_end:UInt32} FOLLOWING) AS cnt1,\n       sum(x) OVER (ROWS {window_size :UInt32} PRECEDING)                                                       AS rows_shorthand\nFROM t\nWHERE category = {category :String}\n  AND type = {type:String};\n\n\n-- Format SQL:\nSELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start: UInt32} PRECEDING AND CURRENT ROW) AS total1, avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end: UInt32} FOLLOWING) AS avg1, count(*) OVER (ORDER BY y RANGE BETWEEN {range_start: UInt32} PRECEDING AND {range_end: UInt32} FOLLOWING) AS cnt1, sum(x) OVER (ROWS {window_size: UInt32} PRECEDING) AS rows_shorthand FROM t WHERE category = {category: String} AND type = {type: String};\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_distinct.sql",
    "content": "-- Origin SQL:\nSELECT count(DISTINCT(RECORD_ID)) FROM RECORD_TABLE\n\n-- Format SQL:\nSELECT count(DISTINCT (RECORD_ID)) FROM RECORD_TABLE;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_distinct_keyword.sql",
    "content": "-- Origin SQL:\nSELECT DISTINCT record_id FROM records \n\n-- Format SQL:\nSELECT DISTINCT record_id FROM records;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_distinct_on_dotted_columns.sql",
    "content": "-- Origin SQL:\nSELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table t\n\n-- Format SQL:\nSELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table AS t;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_distinct_on_keyword.sql",
    "content": "-- Origin SQL:\nSELECT DISTINCT ON(album,artist) record_id FROM records\n\n-- Format SQL:\nSELECT DISTINCT ON (album, artist) record_id FROM records;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_group_by.sql",
    "content": "-- Origin SQL:\nSELECT\n    datacenter,\n    distro,\n    SUM (quantity) AS qty\nFROM\n    servers\nGROUP BY\n    GROUPING SETS(\n    (datacenter,distro),\n    (datacenter),\n    (distro),\n    ()\n);\n\nSELECT\n    datacenter,\n    distro,\n    SUM (quantity) AS qty\nFROM\n    servers\nGROUP BY ALL;\n\n-- Format SQL:\nSELECT datacenter, distro, SUM(quantity) AS qty FROM servers GROUP BY GROUPING SETS((datacenter, distro), (datacenter), (distro), ());\nSELECT datacenter, distro, SUM(quantity) AS qty FROM servers GROUP BY ALL;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_join_only.sql",
    "content": "-- Origin SQL:\nSELECT * FROM \"t1\" JOIN \"t2\" ON true\n\n\n-- Format SQL:\nSELECT * FROM \"t1\" JOIN \"t2\" ON true;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_keyword_in_group_by.sql",
    "content": "-- Origin SQL:\nSELECT\n    toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval,\n    column_name\nFROM table\nWHERE true\nGROUP BY (interval, column_name)\nORDER BY (interval AS i, column_name) ASC\n\n-- Format SQL:\nSELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_keyword_placeholder.sql",
    "content": "-- Origin SQL:\nSELECT {name :String};\nSELECT toString({name :String});\n\n\n\n-- Format SQL:\nSELECT {name: String};\nSELECT toString({name: String});\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_left_join.sql",
    "content": "-- Origin SQL:\nWITH\n    t1 AS\n        (\n            SELECT 1 AS value\n    ),\n    t2 AS\n       (\nSELECT 2 AS value\n    )\nSELECT *\nFROM t1\n         LEFT JOIN t2 ON true\n\n-- Format SQL:\nWITH t1 AS (SELECT 1 AS value), t2 AS (SELECT 2 AS value) SELECT * FROM t1 LEFT JOIN t2 ON true;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_literal_table_name.sql",
    "content": "-- Origin SQL:\nselect table_name from \"information_schema\".\"tables\" limit 1;\n\n\n-- Format SQL:\nSELECT table_name FROM \"information_schema\".\"tables\" LIMIT 1;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_array_and_inner_join.sql",
    "content": "-- Origin SQL:\nSELECT\n    JSONExtractString(t3.props, 'value') AS value\nFROM t1\n    ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1\n    INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id')\n    ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2\n    INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id')\nWHERE value != '';\n\n-- Format SQL:\nSELECT JSONExtractString(t3.props, 'value') AS value FROM t1 ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1 INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id') ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2 INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id') WHERE value != '';\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_array_join.sql",
    "content": "-- Origin SQL:\nSELECT\n    v,\n    j\nFROM t1\n    ARRAY JOIN JSONExtractArrayRaw(a) AS j\n    ARRAY JOIN array(\n    JSONExtractString(j, 'x'),\n    JSONExtractString(j, 'y')\n) AS v;\n\n-- Format SQL:\nSELECT v, j FROM t1 ARRAY JOIN JSONExtractArrayRaw(a) AS j ARRAY JOIN array(JSONExtractString(j, 'x'), JSONExtractString(j, 'y')) AS v;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_except.sql",
    "content": "-- Origin SQL:\nSELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9)\n\n-- Format SQL:\nSELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9);\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_join.sql",
    "content": "-- Origin SQL:\nwith t1 as (\n    select 'value1' as value\n    ), t2 as (\nselect 'value2' as value\n    ), t3 as (\nselect 'value3' as value\n    )\nselect\n    t1.value as value1,\n    t2.value as value2,\n    t3.value as value3\nfrom\n    t1\n        join t2 on true\n        join t3\n        join t4 on true\n        join t5\n\n\n-- Format SQL:\nWITH t1 AS (SELECT 'value1' AS value), t2 AS (SELECT 'value2' AS value), t3 AS (SELECT 'value3' AS value) SELECT t1.value AS value1, t2.value AS value2, t3.value AS value3 FROM t1 JOIN t2 ON true JOIN t3 JOIN t4 ON true JOIN t5;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_line_comment.sql",
    "content": "-- Origin SQL:\nselect\n    -- first line\n    -- second line\n    *\nfrom\n    t0\n\n-- Format SQL:\nSELECT * FROM t0;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_union.sql",
    "content": "-- Origin SQL:\nSELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3\n\n\n-- Format SQL:\nSELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_multi_union_distinct.sql",
    "content": "-- Origin SQL:\nSELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3\n\n-- Format SQL:\nSELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_number_field.sql",
    "content": "-- Origin SQL:\nSELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m as bar\n\n-- Format SQL:\nSELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m AS bar;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_placeholder.sql",
    "content": "-- Origin SQL:\nSELECT * FROM t0 WHERE id = ?;\n\n-- Format SQL:\nSELECT * FROM t0 WHERE id = ?;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_query_parameter.sql",
    "content": "-- Origin SQL:\nSET param_a = 13;\nSET param_b = 'str';\nSET param_c = '2022-08-04 18:30:53';\nSET param_d = {'10': [11, 12], '13': [14, 15]};\n\nSELECT\n    {a: UInt32},\n    {b: String},\n    {c: DateTime},\n    {d: Map(String, Array(UInt8))};\n\nSELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String};\n\n\n-- Format SQL:\nSET param_a=13;\nSET param_b='str';\nSET param_c='2022-08-04 18:30:53';\nSET param_d={'10': [11, 12], '13': [14, 15]};\nSELECT {a: UInt32}, {b: String}, {c: DateTime}, {d: Map(String, Array(UInt8))};\nSELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String};\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_settings_additional_table_filters.sql",
    "content": "-- Origin SQL:\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'};\n\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \\'test\\''};\n\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''};\n\nSELECT * FROM test_table\nSETTINGS additional_table_filters={'test_table': 'id IN (\\'a\\', \\'b\\') AND status = \\'active\\''}\nFORMAT JSON;\n\nSELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) f\nANY LEFT JOIN (SELECT x, y FROM table_1) s ON f.number = s.x\nSETTINGS additional_table_filters={'system.numbers':'number != 3', 'table_1':'x != 2'};\n\n\n-- Format SQL:\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'};\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \\'test\\''};\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''};\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'id IN (\\'a\\', \\'b\\') AND status = \\'active\\''} FORMAT JSON;\nSELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) AS f ANY LEFT JOIN (SELECT x, y FROM table_1) AS s ON f.number = s.x SETTINGS additional_table_filters={'system.numbers': 'number != 3', 'table_1': 'x != 2'};\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_single_quote_table.sql",
    "content": "-- Origin SQL:\nSELECT * FROM 'test_table'\n\n\n-- Format SQL:\nSELECT * FROM 'test_table';\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_string_expr.sql",
    "content": "-- Origin SQL:\nWITH \"abc\" AS (SELECT 1 AS a) SELECT * FROM \"abc\"\n\n\n-- Format SQL:\nWITH \"abc\" AS (SELECT 1 AS a) SELECT * FROM \"abc\";\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_union_distinct.sql",
    "content": "-- Origin SQL:\nSELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON\n\n-- Format SQL:\nSELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas FORMAT JSON;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_variable.sql",
    "content": "-- Origin SQL:\nWITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc\n\n-- Format SQL:\nWITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc;\n"
  },
  {
    "path": "parser/testdata/query/format/select_with_window_function.sql",
    "content": "-- Origin SQL:\nSELECT aggregation_target AS aggregation_target,\n    timestamp AS timestamp,\n    step_0 AS step_0,\n    latest_0 AS latest_0,\n    step_1 AS step_1,\n    latest_1 AS latest_1,\n    step_2 AS step_2,\n    min(latest_2) OVER (PARTITION BY aggregation_target\n    ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2,\n    min(latest_1) OVER w AS latest_1\nFROM t0\nWINDOW w AS (PARTITION BY aggregation_target\n    ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING);\n\n-- Format SQL:\nSELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2, min(latest_1) OVER w AS latest_1 FROM t0 WINDOW w AS (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING);\n"
  },
  {
    "path": "parser/testdata/query/format/select_without_from_where.sql",
    "content": "-- Origin SQL:\nSELECT 1 WHERE 1 = 1;\nSELECT {p :UInt8} WHERE {p :UInt8} = 1;\n\n\n\n-- Format SQL:\nSELECT 1 WHERE 1 = 1;\nSELECT {p: UInt8} WHERE {p: UInt8} = 1;\n"
  },
  {
    "path": "parser/testdata/query/format/set_simple.sql",
    "content": "-- Origin SQL:\nSET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage\n\n-- Format SQL:\nSET max_threads=1, max_insert_threads=0, max_block_size=8192, min_insert_block_size_rows=8192, min_insert_block_size_bytes=1048576;\n"
  },
  {
    "path": "parser/testdata/query/output/access_tuple_with_dot.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 34,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"Name\": {\n              \"Name\": \"tuple\",\n              \"QuoteType\": 1,\n              \"NamePos\": 7,\n              \"NameEnd\": 12\n            },\n            \"Params\": {\n              \"LeftParenPos\": 12,\n              \"RightParenPos\": 24,\n              \"Items\": {\n                \"ListPos\": 14,\n                \"ListEnd\": 23,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 14,\n                      \"LiteralEnd\": 15,\n                      \"Literal\": \"a\"\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 18,\n                      \"LiteralEnd\": 19,\n                      \"Literal\": \"b\"\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 22,\n                      \"LiteralEnd\": 23,\n                      \"Literal\": \"c\"\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Operation\": \".\",\n          \"Index\": {\n            \"NumPos\": 26,\n            \"NumEnd\": 27,\n            \"Literal\": \"3\",\n            \"Base\": 10\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"NumPos\": 29,\n          \"NumEnd\": 34,\n          \"Literal\": \".1234\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 37,\n    \"StatementEnd\": 336,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"toTypeName\",\n            \"QuoteType\": 1,\n            \"NamePos\": 44,\n            \"NameEnd\": 54\n          },\n          \"Params\": {\n            \"LeftParenPos\": 54,\n            \"RightParenPos\": 151,\n            \"Items\": {\n              \"ListPos\": 56,\n              \"ListEnd\": 150,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Name\": {\n                        \"Name\": \"tuple\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 56,\n                        \"NameEnd\": 61\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 61,\n                        \"RightParenPos\": 102,\n                        \"Items\": {\n                          \"ListPos\": 63,\n                          \"ListEnd\": 102,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 63,\n                                \"LiteralEnd\": 64,\n                                \"Literal\": \"a\"\n                              },\n                              \"Alias\": {\n                                \"Name\": \"first\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 69,\n                                \"NameEnd\": 74\n                              }\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 76,\n                                \"LiteralEnd\": 77,\n                                \"Literal\": \"b\"\n                              },\n                              \"Alias\": {\n                                \"Name\": \"second\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 82,\n                                \"NameEnd\": 88\n                              }\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 91,\n                                \"LiteralEnd\": 92,\n                                \"Literal\": \"c\"\n                              },\n                              \"Alias\": {\n                                \"Name\": \"third\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 97,\n                                \"NameEnd\": 102\n                              }\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Operation\": \"::\",\n                    \"RightExpr\": {\n                      \"LeftParenPos\": 111,\n                      \"RightParenPos\": 150,\n                      \"Name\": {\n                        \"Name\": \"Tuple\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 105,\n                        \"NameEnd\": 110\n                      },\n                      \"Columns\": [\n                        {\n                          \"NamePos\": 111,\n                          \"ColumnEnd\": 123,\n                          \"Name\": {\n                            \"Ident\": {\n                              \"Name\": \"first\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 111,\n                              \"NameEnd\": 116\n                            },\n                            \"DotIdent\": null\n                          },\n                          \"Type\": {\n                            \"Name\": {\n                              \"Name\": \"String\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 117,\n                              \"NameEnd\": 123\n                            }\n                          },\n                          \"NotNull\": null,\n                          \"Nullable\": null,\n                          \"DefaultExpr\": null,\n                          \"MaterializedExpr\": null,\n                          \"AliasExpr\": null,\n                          \"Codec\": null,\n                          \"TTL\": null,\n                          \"Comment\": null,\n                          \"CompressionCodec\": null\n                        },\n                        {\n                          \"NamePos\": 124,\n                          \"ColumnEnd\": 137,\n                          \"Name\": {\n                            \"Ident\": {\n                              \"Name\": \"second\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 124,\n                              \"NameEnd\": 130\n                            },\n                            \"DotIdent\": null\n                          },\n                          \"Type\": {\n                            \"Name\": {\n                              \"Name\": \"String\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 131,\n                              \"NameEnd\": 137\n                            }\n                          },\n                          \"NotNull\": null,\n                          \"Nullable\": null,\n                          \"DefaultExpr\": null,\n                          \"MaterializedExpr\": null,\n                          \"AliasExpr\": null,\n                          \"Codec\": null,\n                          \"TTL\": null,\n                          \"Comment\": null,\n                          \"CompressionCodec\": null\n                        },\n                        {\n                          \"NamePos\": 138,\n                          \"ColumnEnd\": 150,\n                          \"Name\": {\n                            \"Ident\": {\n                              \"Name\": \"third\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 138,\n                              \"NameEnd\": 143\n                            },\n                            \"DotIdent\": null\n                          },\n                          \"Type\": {\n                            \"Name\": {\n                              \"Name\": \"String\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 144,\n                              \"NameEnd\": 150\n                            }\n                          },\n                          \"NotNull\": null,\n                          \"Nullable\": null,\n                          \"DefaultExpr\": null,\n                          \"MaterializedExpr\": null,\n                          \"AliasExpr\": null,\n                          \"Codec\": null,\n                          \"TTL\": null,\n                          \"Comment\": null,\n                          \"CompressionCodec\": null\n                        }\n                      ]\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"LeftParenPos\": 161,\n            \"RightParenPos\": 257,\n            \"Items\": {\n              \"ListPos\": 162,\n              \"ListEnd\": 256,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Name\": {\n                        \"Name\": \"tuple\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 162,\n                        \"NameEnd\": 167\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 167,\n                        \"RightParenPos\": 208,\n                        \"Items\": {\n                          \"ListPos\": 169,\n                          \"ListEnd\": 208,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 169,\n                                \"LiteralEnd\": 170,\n                                \"Literal\": \"a\"\n                              },\n                              \"Alias\": {\n                                \"Name\": \"first\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 175,\n                                \"NameEnd\": 180\n                              }\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 182,\n                                \"LiteralEnd\": 183,\n                                \"Literal\": \"b\"\n                              },\n                              \"Alias\": {\n                                \"Name\": \"second\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 188,\n                                \"NameEnd\": 194\n                              }\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 197,\n                                \"LiteralEnd\": 198,\n                                \"Literal\": \"c\"\n                              },\n                              \"Alias\": {\n                                \"Name\": \"third\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 203,\n                                \"NameEnd\": 208\n                              }\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Operation\": \"::\",\n                    \"RightExpr\": {\n                      \"LeftParenPos\": 217,\n                      \"RightParenPos\": 256,\n                      \"Name\": {\n                        \"Name\": \"Tuple\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 211,\n                        \"NameEnd\": 216\n                      },\n                      \"Columns\": [\n                        {\n                          \"NamePos\": 217,\n                          \"ColumnEnd\": 229,\n                          \"Name\": {\n                            \"Ident\": {\n                              \"Name\": \"first\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 217,\n                              \"NameEnd\": 222\n                            },\n                            \"DotIdent\": null\n                          },\n                          \"Type\": {\n                            \"Name\": {\n                              \"Name\": \"String\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 223,\n                              \"NameEnd\": 229\n                            }\n                          },\n                          \"NotNull\": null,\n                          \"Nullable\": null,\n                          \"DefaultExpr\": null,\n                          \"MaterializedExpr\": null,\n                          \"AliasExpr\": null,\n                          \"Codec\": null,\n                          \"TTL\": null,\n                          \"Comment\": null,\n                          \"CompressionCodec\": null\n                        },\n                        {\n                          \"NamePos\": 230,\n                          \"ColumnEnd\": 243,\n                          \"Name\": {\n                            \"Ident\": {\n                              \"Name\": \"second\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 230,\n                              \"NameEnd\": 236\n                            },\n                            \"DotIdent\": null\n                          },\n                          \"Type\": {\n                            \"Name\": {\n                              \"Name\": \"String\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 237,\n                              \"NameEnd\": 243\n                            }\n                          },\n                          \"NotNull\": null,\n                          \"Nullable\": null,\n                          \"DefaultExpr\": null,\n                          \"MaterializedExpr\": null,\n                          \"AliasExpr\": null,\n                          \"Codec\": null,\n                          \"TTL\": null,\n                          \"Comment\": null,\n                          \"CompressionCodec\": null\n                        },\n                        {\n                          \"NamePos\": 244,\n                          \"ColumnEnd\": 256,\n                          \"Name\": {\n                            \"Ident\": {\n                              \"Name\": \"third\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 244,\n                              \"NameEnd\": 249\n                            },\n                            \"DotIdent\": null\n                          },\n                          \"Type\": {\n                            \"Name\": {\n                              \"Name\": \"String\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 250,\n                              \"NameEnd\": 256\n                            }\n                          },\n                          \"NotNull\": null,\n                          \"Nullable\": null,\n                          \"DefaultExpr\": null,\n                          \"MaterializedExpr\": null,\n                          \"AliasExpr\": null,\n                          \"Codec\": null,\n                          \"TTL\": null,\n                          \"Comment\": null,\n                          \"CompressionCodec\": null\n                        }\n                      ]\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          },\n          \"Operation\": \".\",\n          \"Index\": {\n            \"Name\": \"second\",\n            \"QuoteType\": 1,\n            \"NamePos\": 259,\n            \"NameEnd\": 265\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"Name\": {\n              \"Name\": \"tuple\",\n              \"QuoteType\": 1,\n              \"NamePos\": 274,\n              \"NameEnd\": 279\n            },\n            \"Params\": {\n              \"LeftParenPos\": 279,\n              \"RightParenPos\": 291,\n              \"Items\": {\n                \"ListPos\": 281,\n                \"ListEnd\": 290,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 281,\n                      \"LiteralEnd\": 282,\n                      \"Literal\": \"a\"\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 285,\n                      \"LiteralEnd\": 286,\n                      \"Literal\": \"b\"\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 289,\n                      \"LiteralEnd\": 290,\n                      \"Literal\": \"c\"\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Operation\": \".\",\n          \"Index\": {\n            \"NumPos\": 293,\n            \"NumEnd\": 294,\n            \"Literal\": \"3\",\n            \"Base\": 10\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"tupleElement\",\n            \"QuoteType\": 1,\n            \"NamePos\": 303,\n            \"NameEnd\": 315\n          },\n          \"Params\": {\n            \"LeftParenPos\": 315,\n            \"RightParenPos\": 336,\n            \"Items\": {\n              \"ListPos\": 316,\n              \"ListEnd\": 336,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"tuple\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 316,\n                      \"NameEnd\": 321\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 321,\n                      \"RightParenPos\": 333,\n                      \"Items\": {\n                        \"ListPos\": 323,\n                        \"ListEnd\": 332,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"LiteralPos\": 323,\n                              \"LiteralEnd\": 324,\n                              \"Literal\": \"a\"\n                            },\n                            \"Alias\": null\n                          },\n                          {\n                            \"Expr\": {\n                              \"LiteralPos\": 327,\n                              \"LiteralEnd\": 328,\n                              \"Literal\": \"b\"\n                            },\n                            \"Alias\": null\n                          },\n                          {\n                            \"Expr\": {\n                              \"LiteralPos\": 331,\n                              \"LiteralEnd\": 332,\n                              \"Literal\": \"c\"\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"NumPos\": 335,\n                    \"NumEnd\": 336,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/create_window_view.sql.golden.json",
    "content": "[\n  {\n    \"CreatePos\": 0,\n    \"StatementEnd\": 295,\n    \"OrReplace\": true,\n    \"Name\": {\n      \"Database\": null,\n      \"Table\": {\n        \"Name\": \"asdf\",\n        \"QuoteType\": 1,\n        \"NamePos\": 23,\n        \"NameEnd\": 27\n      }\n    },\n    \"IfNotExists\": false,\n    \"UUID\": null,\n    \"OnCluster\": null,\n    \"TableSchema\": null,\n    \"Comment\": null,\n    \"SubQuery\": {\n      \"HasParen\": false,\n      \"Select\": {\n        \"SelectPos\": 31,\n        \"StatementEnd\": 295,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 38,\n              \"NameEnd\": 40\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"price\",\n                \"QuoteType\": 1,\n                \"NamePos\": 49,\n                \"NameEnd\": 54\n              },\n              \"Operation\": \"*\",\n              \"RightExpr\": {\n                \"NumPos\": 57,\n                \"NumEnd\": 60,\n                \"Literal\": \"1.5\",\n                \"Base\": 10\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"computed_value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 64,\n              \"NameEnd\": 78\n            }\n          },\n          {\n            \"Expr\": {\n              \"Function\": {\n                \"Name\": {\n                  \"Name\": \"row_number\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 87,\n                  \"NameEnd\": 97\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 97,\n                  \"RightParenPos\": 98,\n                  \"Items\": {\n                    \"ListPos\": 98,\n                    \"ListEnd\": 98,\n                    \"HasDistinct\": false,\n                    \"Items\": []\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"OverPos\": 100,\n              \"OverExpr\": {\n                \"LeftParenPos\": 105,\n                \"RightParenPos\": 238,\n                \"WindowName\": null,\n                \"PartitionBy\": {\n                  \"PartitionPos\": 105,\n                  \"Expr\": {\n                    \"ListPos\": 131,\n                    \"ListEnd\": 139,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"category\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 131,\n                          \"NameEnd\": 139\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  }\n                },\n                \"OrderBy\": {\n                  \"OrderPos\": 151,\n                  \"ListEnd\": 170,\n                  \"Items\": [\n                    {\n                      \"OrderPos\": 151,\n                      \"Expr\": {\n                        \"Name\": \"created_at\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 160,\n                        \"NameEnd\": 170\n                      },\n                      \"Alias\": null,\n                      \"Direction\": \"\",\n                      \"Fill\": null\n                    }\n                  ],\n                  \"Interpolate\": null\n                },\n                \"Frame\": {\n                  \"FramePos\": 182,\n                  \"Type\": \"RANGE\",\n                  \"Extend\": {\n                    \"Expr\": null,\n                    \"Between\": {\n                      \"Number\": {\n                        \"NumPos\": 196,\n                        \"NumEnd\": 200,\n                        \"Literal\": \"3600\",\n                        \"Base\": 10\n                      },\n                      \"EndPos\": 210,\n                      \"Direction\": \"PRECEDING\"\n                    },\n                    \"AndPos\": 211,\n                    \"And\": {\n                      \"CurrentPos\": 215,\n                      \"RowEnd\": 239\n                    }\n                  }\n                }\n              }\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"rn\",\n              \"QuoteType\": 1,\n              \"NamePos\": 249,\n              \"NameEnd\": 251\n            }\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 252,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 257,\n              \"TableEnd\": 269,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"source_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 257,\n                  \"NameEnd\": 269\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 269,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": {\n          \"WherePos\": 270,\n          \"Expr\": {\n            \"LeftExpr\": {\n              \"Name\": \"date\",\n              \"QuoteType\": 1,\n              \"NamePos\": 276,\n              \"NameEnd\": 280\n            },\n            \"Operation\": \"\\u003e=\",\n            \"RightExpr\": {\n              \"LiteralPos\": 285,\n              \"LiteralEnd\": 295,\n              \"Literal\": \"2023-01-01\"\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          }\n        },\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/query_with_expr_compare.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 225,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"date\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 11\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"path\",\n          \"QuoteType\": 1,\n          \"NamePos\": 13,\n          \"NameEnd\": 17\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"Name\": {\n              \"Name\": \"splitByChar\",\n              \"QuoteType\": 1,\n              \"NamePos\": 19,\n              \"NameEnd\": 30\n            },\n            \"Params\": {\n              \"LeftParenPos\": 30,\n              \"RightParenPos\": 40,\n              \"Items\": {\n                \"ListPos\": 32,\n                \"ListEnd\": 40,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LiteralPos\": 32,\n                      \"LiteralEnd\": 33,\n                      \"Literal\": \"/\"\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"path\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 36,\n                      \"NameEnd\": 40\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Params\": {\n            \"LeftBracketPos\": 41,\n            \"RightBracketPos\": 43,\n            \"Items\": {\n              \"ListPos\": 42,\n              \"ListEnd\": 43,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"NumPos\": 42,\n                    \"NumEnd\": 43,\n                    \"Literal\": \"2\",\n                    \"Base\": 10\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"path_b\",\n          \"QuoteType\": 1,\n          \"NamePos\": 48,\n          \"NameEnd\": 54\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 55,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 59,\n          \"TableEnd\": 121,\n          \"Alias\": null,\n          \"Expr\": {\n            \"HasParen\": true,\n            \"Select\": {\n              \"SelectPos\": 65,\n              \"StatementEnd\": 121,\n              \"With\": null,\n              \"Top\": null,\n              \"HasDistinct\": false,\n              \"DistinctOn\": null,\n              \"SelectItems\": [\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 73,\n                    \"LiteralEnd\": 90,\n                    \"Literal\": \"pathA/pathB/pathC\"\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"path\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 95,\n                    \"NameEnd\": 99\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 102,\n                    \"LiteralEnd\": 112,\n                    \"Literal\": \"2024-09-10\"\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"date\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 117,\n                    \"NameEnd\": 121\n                  }\n                }\n              ],\n              \"From\": null,\n              \"Window\": null,\n              \"Prewhere\": null,\n              \"Where\": null,\n              \"GroupBy\": null,\n              \"WithTotal\": false,\n              \"Having\": null,\n              \"OrderBy\": null,\n              \"LimitBy\": null,\n              \"Limit\": null,\n              \"Settings\": null,\n              \"Format\": null,\n              \"UnionAll\": null,\n              \"UnionDistinct\": null,\n              \"Except\": null\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 121,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 128,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Expr\": {\n            \"Name\": {\n              \"Name\": \"toDate\",\n              \"QuoteType\": 1,\n              \"NamePos\": 134,\n              \"NameEnd\": 140\n            },\n            \"Params\": {\n              \"LeftParenPos\": 140,\n              \"RightParenPos\": 145,\n              \"Items\": {\n                \"ListPos\": 141,\n                \"ListEnd\": 145,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"date\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 141,\n                      \"NameEnd\": 145\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Between\": {\n            \"LiteralPos\": 156,\n            \"LiteralEnd\": 166,\n            \"Literal\": \"2024-09-01\"\n          },\n          \"AndPos\": 168,\n          \"And\": {\n            \"LiteralPos\": 173,\n            \"LiteralEnd\": 183,\n            \"Literal\": \"2024-09-30\"\n          }\n        },\n        \"Operation\": \"AND\",\n        \"RightExpr\": {\n          \"LeftExpr\": {\n            \"Object\": {\n              \"Name\": {\n                \"Name\": \"splitByChar\",\n                \"QuoteType\": 1,\n                \"NamePos\": 191,\n                \"NameEnd\": 202\n              },\n              \"Params\": {\n                \"LeftParenPos\": 202,\n                \"RightParenPos\": 212,\n                \"Items\": {\n                  \"ListPos\": 204,\n                  \"ListEnd\": 212,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"LiteralPos\": 204,\n                        \"LiteralEnd\": 205,\n                        \"Literal\": \"/\"\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"Name\": \"path\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 208,\n                        \"NameEnd\": 212\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Params\": {\n              \"LeftBracketPos\": 213,\n              \"RightBracketPos\": 215,\n              \"Items\": {\n                \"ListPos\": 214,\n                \"ListEnd\": 215,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"NumPos\": 214,\n                      \"NumEnd\": 215,\n                      \"Literal\": \"1\",\n                      \"Base\": 10\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            }\n          },\n          \"Operation\": \"=\",\n          \"RightExpr\": {\n            \"LiteralPos\": 220,\n            \"LiteralEnd\": 225,\n            \"Literal\": \"pathA\"\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_case_multiple_when.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 190,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 11,\n          \"NameEnd\": 11\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"CasePos\": 18,\n          \"EndPos\": 0,\n          \"Expr\": null,\n          \"Whens\": [\n            {\n              \"WhenPos\": 31,\n              \"ThenPos\": 52,\n              \"When\": {\n                \"LeftExpr\": {\n                  \"Name\": \"col2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 36,\n                  \"NameEnd\": 40\n                },\n                \"Operation\": \"=\",\n                \"RightExpr\": {\n                  \"LiteralPos\": 44,\n                  \"LiteralEnd\": 50,\n                  \"Literal\": \"value1\"\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Then\": {\n                \"LiteralPos\": 58,\n                \"LiteralEnd\": 63,\n                \"Literal\": \"when1\"\n              },\n              \"ElsePos\": 0,\n              \"Else\": null\n            },\n            {\n              \"WhenPos\": 73,\n              \"ThenPos\": 94,\n              \"When\": {\n                \"LeftExpr\": {\n                  \"Name\": \"col3\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 78,\n                  \"NameEnd\": 82\n                },\n                \"Operation\": \"=\",\n                \"RightExpr\": {\n                  \"LiteralPos\": 86,\n                  \"LiteralEnd\": 92,\n                  \"Literal\": \"value2\"\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              },\n              \"Then\": {\n                \"LiteralPos\": 100,\n                \"LiteralEnd\": 105,\n                \"Literal\": \"when2\"\n              },\n              \"ElsePos\": 0,\n              \"Else\": null\n            }\n          ],\n          \"ElsePos\": 115,\n          \"Else\": {\n            \"LiteralPos\": 121,\n            \"LiteralEnd\": 125,\n            \"Literal\": \"else\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"check_result\",\n          \"QuoteType\": 1,\n          \"NamePos\": 138,\n          \"NameEnd\": 150\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 151,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 156,\n          \"TableEnd\": 166,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"table_name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 156,\n              \"NameEnd\": 166\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 166,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 167,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Name\": \"col1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 173,\n          \"NameEnd\": 177\n        },\n        \"Operation\": \"=\",\n        \"RightExpr\": {\n          \"LiteralPos\": 181,\n          \"LiteralEnd\": 190,\n          \"Literal\": \"123456789\"\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_case_when_exists.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 205,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 11,\n          \"NameEnd\": 11\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"CasePos\": 18,\n          \"EndPos\": 0,\n          \"Expr\": null,\n          \"Whens\": [\n            {\n              \"WhenPos\": 31,\n              \"ThenPos\": 110,\n              \"When\": {\n                \"Name\": {\n                  \"Name\": \"EXISTS\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 36,\n                  \"NameEnd\": 42\n                },\n                \"Params\": {\n                  \"LeftParenPos\": 42,\n                  \"RightParenPos\": 100,\n                  \"Items\": {\n                    \"ListPos\": 43,\n                    \"ListEnd\": 99,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"SelectPos\": 43,\n                          \"StatementEnd\": 99,\n                          \"With\": null,\n                          \"Top\": null,\n                          \"HasDistinct\": false,\n                          \"DistinctOn\": null,\n                          \"SelectItems\": [\n                            {\n                              \"Expr\": {\n                                \"NumPos\": 50,\n                                \"NumEnd\": 51,\n                                \"Literal\": \"1\",\n                                \"Base\": 10\n                              },\n                              \"Modifiers\": [],\n                              \"Alias\": null\n                            }\n                          ],\n                          \"From\": {\n                            \"FromPos\": 56,\n                            \"Expr\": {\n                              \"Table\": {\n                                \"TablePos\": 61,\n                                \"TableEnd\": 71,\n                                \"Alias\": null,\n                                \"Expr\": {\n                                  \"Database\": null,\n                                  \"Table\": {\n                                    \"Name\": \"table_name\",\n                                    \"QuoteType\": 1,\n                                    \"NamePos\": 61,\n                                    \"NameEnd\": 71\n                                  }\n                                },\n                                \"HasFinal\": false\n                              },\n                              \"StatementEnd\": 71,\n                              \"SampleRatio\": null,\n                              \"HasFinal\": false\n                            }\n                          },\n                          \"Window\": null,\n                          \"Prewhere\": null,\n                          \"Where\": {\n                            \"WherePos\": 76,\n                            \"Expr\": {\n                              \"LeftExpr\": {\n                                \"Name\": \"col1\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 82,\n                                \"NameEnd\": 86\n                              },\n                              \"Operation\": \"=\",\n                              \"RightExpr\": {\n                                \"LiteralPos\": 90,\n                                \"LiteralEnd\": 99,\n                                \"Literal\": \"999999999\"\n                              },\n                              \"HasGlobal\": false,\n                              \"HasNot\": false\n                            }\n                          },\n                          \"GroupBy\": null,\n                          \"WithTotal\": false,\n                          \"Having\": null,\n                          \"OrderBy\": null,\n                          \"LimitBy\": null,\n                          \"Limit\": null,\n                          \"Settings\": null,\n                          \"Format\": null,\n                          \"UnionAll\": null,\n                          \"UnionDistinct\": null,\n                          \"Except\": null\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  },\n                  \"ColumnArgList\": null\n                }\n              },\n              \"Then\": {\n                \"LiteralPos\": 116,\n                \"LiteralEnd\": 120,\n                \"Literal\": \"then\"\n              },\n              \"ElsePos\": 0,\n              \"Else\": null\n            }\n          ],\n          \"ElsePos\": 130,\n          \"Else\": {\n            \"LiteralPos\": 136,\n            \"LiteralEnd\": 140,\n            \"Literal\": \"else\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"check_result\",\n          \"QuoteType\": 1,\n          \"NamePos\": 153,\n          \"NameEnd\": 165\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 166,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 171,\n          \"TableEnd\": 181,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"table_name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 171,\n              \"NameEnd\": 181\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 181,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 182,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Name\": \"col1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 188,\n          \"NameEnd\": 192\n        },\n        \"Operation\": \"=\",\n        \"RightExpr\": {\n          \"LiteralPos\": 196,\n          \"LiteralEnd\": 205,\n          \"Literal\": \"123456789\"\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_cast.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 34,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CastPos\": 7,\n          \"Expr\": {\n            \"NumPos\": 12,\n            \"NumEnd\": 13,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"Separator\": \"as\",\n          \"AsPos\": 14,\n          \"AsType\": {\n            \"Name\": {\n              \"Name\": \"Float64\",\n              \"QuoteType\": 1,\n              \"NamePos\": 17,\n              \"NameEnd\": 24\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 29,\n          \"NameEnd\": 34\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 36,\n    \"StatementEnd\": 70,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CastPos\": 43,\n          \"Expr\": {\n            \"NumPos\": 48,\n            \"NumEnd\": 49,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"Separator\": \",\",\n          \"AsPos\": 49,\n          \"AsType\": {\n            \"LiteralPos\": 52,\n            \"LiteralEnd\": 59,\n            \"Literal\": \"Float64\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 65,\n          \"NameEnd\": 70\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 72,\n    \"StatementEnd\": 102,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LeftParenPos\": 79,\n          \"RightParenPos\": 92,\n          \"Items\": {\n            \"ListPos\": 80,\n            \"ListEnd\": 92,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"NumPos\": 80,\n                  \"NumEnd\": 81,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Alias\": {\n                  \"Name\": \"Float64\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 85,\n                  \"NameEnd\": 92\n                }\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 97,\n          \"NameEnd\": 102\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 104,\n    \"StatementEnd\": 130,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"NumPos\": 111,\n            \"NumEnd\": 112,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"Operation\": \"::\",\n          \"RightExpr\": {\n            \"Name\": \"Float64\",\n            \"QuoteType\": 1,\n            \"NamePos\": 114,\n            \"NameEnd\": 121\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 125,\n          \"NameEnd\": 130\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_column_alias_string.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 23,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LiteralPos\": 8,\n          \"LiteralEnd\": 11,\n          \"Literal\": \"abc\"\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value2\",\n          \"QuoteType\": 2,\n          \"NamePos\": 17,\n          \"NameEnd\": 23\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 27,\n    \"StatementEnd\": 52,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"$abc\",\n          \"QuoteType\": 1,\n          \"NamePos\": 34,\n          \"NameEnd\": 38\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"a$$bc\",\n          \"QuoteType\": 1,\n          \"NamePos\": 40,\n          \"NameEnd\": 45\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"abc$$\",\n          \"QuoteType\": 1,\n          \"NamePos\": 47,\n          \"NameEnd\": 52\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_concat_expr.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 16,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"LiteralPos\": 8,\n            \"LiteralEnd\": 9,\n            \"Literal\": \"a\"\n          },\n          \"Operation\": \"||\",\n          \"RightExpr\": {\n            \"LiteralPos\": 15,\n            \"LiteralEnd\": 16,\n            \"Literal\": \"b\"\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 19,\n    \"StatementEnd\": 42,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"LeftExpr\": {\n              \"LiteralPos\": 27,\n              \"LiteralEnd\": 28,\n              \"Literal\": \"a\"\n            },\n            \"Operation\": \"||\",\n            \"RightExpr\": {\n              \"LiteralPos\": 34,\n              \"LiteralEnd\": 35,\n              \"Literal\": \"b\"\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"Operation\": \"||\",\n          \"RightExpr\": {\n            \"LiteralPos\": 41,\n            \"LiteralEnd\": 42,\n            \"Literal\": \"c\"\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 45,\n    \"StatementEnd\": 73,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"LeftExpr\": {\n              \"LiteralPos\": 53,\n              \"LiteralEnd\": 54,\n              \"Literal\": \"a\"\n            },\n            \"Operation\": \"||\",\n            \"RightExpr\": {\n              \"LiteralPos\": 60,\n              \"LiteralEnd\": 61,\n              \"Literal\": \"b\"\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"Operation\": \"||\",\n          \"RightExpr\": {\n            \"LeftExpr\": {\n              \"LiteralPos\": 67,\n              \"LiteralEnd\": 68,\n              \"Literal\": \"c\"\n            },\n            \"Operation\": \"+\",\n            \"RightExpr\": {\n              \"NumPos\": 72,\n              \"NumEnd\": 73,\n              \"Literal\": \"5\",\n              \"Base\": 10\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_expr.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 10,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"NumPos\": 7,\n            \"NumEnd\": 8,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"Operation\": \"+\",\n          \"RightExpr\": {\n            \"NumPos\": 9,\n            \"NumEnd\": 10,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_extract_with_regex.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 476,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"COUNT\",\n            \"QuoteType\": 1,\n            \"NamePos\": 9,\n            \"NameEnd\": 14\n          },\n          \"Params\": {\n            \"LeftParenPos\": 14,\n            \"RightParenPos\": 16,\n            \"Items\": {\n              \"ListPos\": 15,\n              \"ListEnd\": 16,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"NumPos\": 15,\n                    \"NumEnd\": 16,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"SRC_TYPE\",\n          \"QuoteType\": 1,\n          \"NamePos\": 19,\n          \"NameEnd\": 27\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"NODE_CLASS\",\n          \"QuoteType\": 1,\n          \"NamePos\": 29,\n          \"NameEnd\": 39\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"PORT\",\n          \"QuoteType\": 1,\n          \"NamePos\": 41,\n          \"NameEnd\": 45\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"CLIENT_PORT\",\n          \"QuoteType\": 1,\n          \"NamePos\": 47,\n          \"NameEnd\": 58\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 59,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 66,\n          \"TableEnd\": 76,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": {\n              \"Name\": \"test\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 70\n            },\n            \"Table\": {\n              \"Name\": \"table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 71,\n              \"NameEnd\": 76\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 76,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 77,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LeftExpr\": {\n            \"LeftExpr\": {\n              \"Name\": \"app_id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 85,\n              \"NameEnd\": 91\n            },\n            \"Operation\": \"=\",\n            \"RightExpr\": {\n              \"NumPos\": 94,\n              \"NumEnd\": 103,\n              \"Literal\": \"999118646\",\n              \"Base\": 10\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"Operation\": \"AND\",\n          \"RightExpr\": {\n            \"LeftExpr\": {\n              \"Name\": {\n                \"Name\": \"toUnixTimestamp\",\n                \"QuoteType\": 1,\n                \"NamePos\": 110,\n                \"NameEnd\": 125\n              },\n              \"Params\": {\n                \"LeftParenPos\": 125,\n                \"RightParenPos\": 135,\n                \"Items\": {\n                  \"ListPos\": 126,\n                  \"ListEnd\": 135,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"timestamp\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 126,\n                        \"NameEnd\": 135\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              }\n            },\n            \"Operation\": \"\\u003e=\",\n            \"RightExpr\": {\n              \"NumPos\": 140,\n              \"NumEnd\": 150,\n              \"Literal\": \"1740366695\",\n              \"Base\": 10\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Operation\": \"AND\",\n        \"RightExpr\": {\n          \"LeftExpr\": {\n            \"Name\": {\n              \"Name\": \"toUnixTimestamp\",\n              \"QuoteType\": 1,\n              \"NamePos\": 157,\n              \"NameEnd\": 172\n            },\n            \"Params\": {\n              \"LeftParenPos\": 172,\n              \"RightParenPos\": 182,\n              \"Items\": {\n                \"ListPos\": 173,\n                \"ListEnd\": 182,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"timestamp\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 173,\n                      \"NameEnd\": 182\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Operation\": \"\\u003c=\",\n          \"RightExpr\": {\n            \"NumPos\": 187,\n            \"NumEnd\": 197,\n            \"Literal\": \"1740377495\",\n            \"Base\": 10\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": {\n      \"GroupByPos\": 198,\n      \"GroupByEnd\": 465,\n      \"AggregateType\": \"\",\n      \"Expr\": {\n        \"ListPos\": 209,\n        \"ListEnd\": 464,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"CasePos\": 209,\n              \"EndPos\": 0,\n              \"Expr\": null,\n              \"Whens\": [\n                {\n                  \"WhenPos\": 218,\n                  \"ThenPos\": 275,\n                  \"When\": {\n                    \"LeftExpr\": {\n                      \"Name\": {\n                        \"Name\": \"length\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 223,\n                        \"NameEnd\": 229\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 229,\n                        \"RightParenPos\": 269,\n                        \"Items\": {\n                          \"ListPos\": 230,\n                          \"ListEnd\": 268,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"ExtractPos\": 230,\n                                \"ExtractEnd\": 268,\n                                \"Parameters\": [\n                                  {\n                                    \"Name\": \"instance\",\n                                    \"QuoteType\": 1,\n                                    \"NamePos\": 238,\n                                    \"NameEnd\": 246\n                                  },\n                                  {\n                                    \"LiteralPos\": 249,\n                                    \"LiteralEnd\": 267,\n                                    \"Literal\": \"((\\\\\\\\d+\\\\\\\\.){3}\\\\\\\\d+)\"\n                                  }\n                                ]\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Operation\": \"\\u003e\",\n                    \"RightExpr\": {\n                      \"NumPos\": 273,\n                      \"NumEnd\": 274,\n                      \"Literal\": \"0\",\n                      \"Base\": 10\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Then\": {\n                    \"Name\": \"instance\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 280,\n                    \"NameEnd\": 288\n                  },\n                  \"ElsePos\": 0,\n                  \"Else\": null\n                }\n              ],\n              \"ElsePos\": 293,\n              \"Else\": {\n                \"LiteralPos\": 299,\n                \"LiteralEnd\": 302,\n                \"Literal\": \"空\"\n              }\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"CasePos\": 313,\n              \"EndPos\": 0,\n              \"Expr\": null,\n              \"Whens\": [\n                {\n                  \"WhenPos\": 322,\n                  \"ThenPos\": 380,\n                  \"When\": {\n                    \"LeftExpr\": {\n                      \"Name\": {\n                        \"Name\": \"length\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 327,\n                        \"NameEnd\": 333\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 333,\n                        \"RightParenPos\": 374,\n                        \"Items\": {\n                          \"ListPos\": 334,\n                          \"ListEnd\": 373,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"ExtractPos\": 334,\n                                \"ExtractEnd\": 373,\n                                \"Parameters\": [\n                                  {\n                                    \"Name\": \"client_ip\",\n                                    \"QuoteType\": 1,\n                                    \"NamePos\": 342,\n                                    \"NameEnd\": 351\n                                  },\n                                  {\n                                    \"LiteralPos\": 354,\n                                    \"LiteralEnd\": 372,\n                                    \"Literal\": \"((\\\\\\\\d+\\\\\\\\.){3}\\\\\\\\d+)\"\n                                  }\n                                ]\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Operation\": \"\\u003e\",\n                    \"RightExpr\": {\n                      \"NumPos\": 378,\n                      \"NumEnd\": 379,\n                      \"Literal\": \"0\",\n                      \"Base\": 10\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Then\": {\n                    \"Name\": \"client_ip\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 385,\n                    \"NameEnd\": 394\n                  },\n                  \"ElsePos\": 0,\n                  \"Else\": null\n                }\n              ],\n              \"ElsePos\": 399,\n              \"Else\": {\n                \"LiteralPos\": 405,\n                \"LiteralEnd\": 408,\n                \"Literal\": \"空\"\n              }\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"src_type\",\n              \"QuoteType\": 1,\n              \"NamePos\": 419,\n              \"NameEnd\": 427\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"node_class\",\n              \"QuoteType\": 1,\n              \"NamePos\": 431,\n              \"NameEnd\": 441\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"port\",\n              \"QuoteType\": 1,\n              \"NamePos\": 445,\n              \"NameEnd\": 449\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"client_port\",\n              \"QuoteType\": 1,\n              \"NamePos\": 453,\n              \"NameEnd\": 464\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"WithCube\": false,\n      \"WithRollup\": false,\n      \"WithTotals\": false\n    },\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": {\n      \"LimitPos\": 465,\n      \"Limit\": {\n        \"NumPos\": 471,\n        \"NumEnd\": 476,\n        \"Literal\": \"10000\",\n        \"Base\": 10\n      },\n      \"Offset\": null\n    },\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_item_with_modifiers.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 35,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"c0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 9\n        },\n        \"Modifiers\": [\n          {\n            \"Name\": {\n              \"Name\": \"REPLACE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 10,\n              \"NameEnd\": 17\n            },\n            \"Params\": {\n              \"LeftParenPos\": 17,\n              \"RightParenPos\": 26,\n              \"Items\": {\n                \"ListPos\": 18,\n                \"ListEnd\": 26,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"c0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 18,\n                      \"NameEnd\": 20\n                    },\n                    \"Alias\": {\n                      \"Name\": \"c1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 24,\n                      \"NameEnd\": 26\n                    }\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          }\n        ],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 28,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 33,\n          \"TableEnd\": 35,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 33,\n              \"NameEnd\": 35\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 35,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 37,\n    \"StatementEnd\": 73,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 44,\n          \"NameEnd\": 44\n        },\n        \"Modifiers\": [\n          {\n            \"Name\": {\n              \"Name\": \"REPLACE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 46,\n              \"NameEnd\": 53\n            },\n            \"Params\": {\n              \"LeftParenPos\": 53,\n              \"RightParenPos\": 64,\n              \"Items\": {\n                \"ListPos\": 54,\n                \"ListEnd\": 64,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Name\": \"i\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 54,\n                        \"NameEnd\": 55\n                      },\n                      \"Operation\": \"+\",\n                      \"RightExpr\": {\n                        \"NumPos\": 58,\n                        \"NumEnd\": 59,\n                        \"Literal\": \"1\",\n                        \"Base\": 10\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": {\n                      \"Name\": \"i\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 63,\n                      \"NameEnd\": 64\n                    }\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          }\n        ],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 66,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 71,\n          \"TableEnd\": 73,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 71,\n              \"NameEnd\": 73\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 73,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 75,\n    \"StatementEnd\": 133,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 82,\n          \"NameEnd\": 82\n        },\n        \"Modifiers\": [\n          {\n            \"Name\": {\n              \"Name\": \"REPLACE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 84,\n              \"NameEnd\": 91\n            },\n            \"Params\": {\n              \"LeftParenPos\": 91,\n              \"RightParenPos\": 102,\n              \"Items\": {\n                \"ListPos\": 92,\n                \"ListEnd\": 102,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Name\": \"i\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 92,\n                        \"NameEnd\": 93\n                      },\n                      \"Operation\": \"+\",\n                      \"RightExpr\": {\n                        \"NumPos\": 96,\n                        \"NumEnd\": 97,\n                        \"Literal\": \"1\",\n                        \"Base\": 10\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": {\n                      \"Name\": \"i\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 101,\n                      \"NameEnd\": 102\n                    }\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"EXCEPT\",\n              \"QuoteType\": 1,\n              \"NamePos\": 104,\n              \"NameEnd\": 110\n            },\n            \"Params\": {\n              \"LeftParenPos\": 111,\n              \"RightParenPos\": 113,\n              \"Items\": {\n                \"ListPos\": 112,\n                \"ListEnd\": 113,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"j\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 112,\n                      \"NameEnd\": 113\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          {\n            \"Name\": {\n              \"Name\": \"APPLY\",\n              \"QuoteType\": 1,\n              \"NamePos\": 115,\n              \"NameEnd\": 120\n            },\n            \"Params\": {\n              \"LeftParenPos\": 120,\n              \"RightParenPos\": 124,\n              \"Items\": {\n                \"ListPos\": 121,\n                \"ListEnd\": 124,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"sum\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 121,\n                      \"NameEnd\": 124\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          }\n        ],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 126,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 131,\n          \"TableEnd\": 133,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 131,\n              \"NameEnd\": 133\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 133,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_json_type.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 24,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"a\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 8\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"a\",\n              \"QuoteType\": 1,\n              \"NamePos\": 10,\n              \"NameEnd\": 11\n            },\n            {\n              \"Name\": \"b\",\n              \"QuoteType\": 1,\n              \"NamePos\": 12,\n              \"NameEnd\": 13\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"a\",\n              \"QuoteType\": 1,\n              \"NamePos\": 15,\n              \"NameEnd\": 16\n            },\n            {\n              \"Name\": \"b\",\n              \"QuoteType\": 1,\n              \"NamePos\": 17,\n              \"NameEnd\": 18\n            },\n            {\n              \"Name\": \"c\",\n              \"QuoteType\": 1,\n              \"NamePos\": 19,\n              \"NameEnd\": 20\n            },\n            {\n              \"Name\": \"d\",\n              \"QuoteType\": 1,\n              \"NamePos\": 21,\n              \"NameEnd\": 22\n            },\n            {\n              \"Name\": \"e\",\n              \"QuoteType\": 1,\n              \"NamePos\": 23,\n              \"NameEnd\": 24\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 26,\n    \"StatementEnd\": 75,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"JSON_TYPE\",\n            \"QuoteType\": 1,\n            \"NamePos\": 33,\n            \"NameEnd\": 42\n          },\n          \"Params\": {\n            \"LeftParenPos\": 42,\n            \"RightParenPos\": 75,\n            \"Items\": {\n              \"ListPos\": 44,\n              \"ListEnd\": 74,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 44,\n                    \"LiteralEnd\": 67,\n                    \"Literal\": \"{\\\"a\\\": 1, \\\"b\\\": {\\\"c\\\": 2}}\"\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 71,\n                    \"LiteralEnd\": 74,\n                    \"Literal\": \"$.b\"\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 78,\n    \"StatementEnd\": 114,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CastPos\": 85,\n          \"Expr\": {\n            \"Name\": \"some\",\n            \"QuoteType\": 1,\n            \"NamePos\": 90,\n            \"NameEnd\": 94\n          },\n          \"Separator\": \",\",\n          \"AsPos\": 94,\n          \"AsType\": {\n            \"LiteralPos\": 97,\n            \"LiteralEnd\": 103,\n            \"Literal\": \"String\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 109,\n          \"NameEnd\": 114\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 116,\n    \"StatementEnd\": 157,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CastPos\": 123,\n          \"Expr\": {\n            \"Fields\": [\n              {\n                \"Name\": \"some\",\n                \"QuoteType\": 1,\n                \"NamePos\": 128,\n                \"NameEnd\": 132\n              },\n              {\n                \"Name\": \"long\",\n                \"QuoteType\": 1,\n                \"NamePos\": 133,\n                \"NameEnd\": 137\n              }\n            ]\n          },\n          \"Separator\": \",\",\n          \"AsPos\": 137,\n          \"AsType\": {\n            \"LiteralPos\": 140,\n            \"LiteralEnd\": 146,\n            \"Literal\": \"String\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 152,\n          \"NameEnd\": 157\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 159,\n    \"StatementEnd\": 205,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CastPos\": 166,\n          \"Expr\": {\n            \"Fields\": [\n              {\n                \"Name\": \"some\",\n                \"QuoteType\": 1,\n                \"NamePos\": 171,\n                \"NameEnd\": 175\n              },\n              {\n                \"Name\": \"long\",\n                \"QuoteType\": 1,\n                \"NamePos\": 176,\n                \"NameEnd\": 180\n              },\n              {\n                \"Name\": \"json\",\n                \"QuoteType\": 1,\n                \"NamePos\": 181,\n                \"NameEnd\": 185\n              }\n            ]\n          },\n          \"Separator\": \",\",\n          \"AsPos\": 185,\n          \"AsType\": {\n            \"LiteralPos\": 188,\n            \"LiteralEnd\": 194,\n            \"Literal\": \"String\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 200,\n          \"NameEnd\": 205\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 207,\n    \"StatementEnd\": 258,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CastPos\": 214,\n          \"Expr\": {\n            \"Fields\": [\n              {\n                \"Name\": \"some\",\n                \"QuoteType\": 1,\n                \"NamePos\": 219,\n                \"NameEnd\": 223\n              },\n              {\n                \"Name\": \"long\",\n                \"QuoteType\": 1,\n                \"NamePos\": 224,\n                \"NameEnd\": 228\n              },\n              {\n                \"Name\": \"json\",\n                \"QuoteType\": 1,\n                \"NamePos\": 229,\n                \"NameEnd\": 233\n              },\n              {\n                \"Name\": \"path\",\n                \"QuoteType\": 1,\n                \"NamePos\": 234,\n                \"NameEnd\": 238\n              }\n            ]\n          },\n          \"Separator\": \",\",\n          \"AsPos\": 238,\n          \"AsType\": {\n            \"LiteralPos\": 241,\n            \"LiteralEnd\": 247,\n            \"Literal\": \"String\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 253,\n          \"NameEnd\": 258\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_keyword_alias_no_as.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 28,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LiteralPos\": 8,\n          \"LiteralEnd\": 11,\n          \"Literal\": \"Joe\"\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 13,\n          \"NameEnd\": 17\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 18,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 23,\n          \"TableEnd\": 28,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"users\",\n              \"QuoteType\": 1,\n              \"NamePos\": 23,\n              \"NameEnd\": 28\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 28,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_timestamp.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 47,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"Timestamp\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 16\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 17,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 22,\n          \"TableEnd\": 28,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"events\",\n              \"QuoteType\": 1,\n              \"NamePos\": 22,\n              \"NameEnd\": 28\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 28,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 29,\n      \"ListEnd\": 47,\n      \"Items\": [\n        {\n          \"OrderPos\": 29,\n          \"Expr\": {\n            \"Name\": \"Timestamp\",\n            \"QuoteType\": 1,\n            \"NamePos\": 38,\n            \"NameEnd\": 47\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": null\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_with_fill_basic.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 151,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"n\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 8\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"source\",\n          \"QuoteType\": 1,\n          \"NamePos\": 10,\n          \"NameEnd\": 16\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 17,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 22,\n          \"TableEnd\": 124,\n          \"Alias\": null,\n          \"Expr\": {\n            \"HasParen\": true,\n            \"Select\": {\n              \"SelectPos\": 27,\n              \"StatementEnd\": 124,\n              \"With\": null,\n              \"Top\": null,\n              \"HasDistinct\": false,\n              \"DistinctOn\": null,\n              \"SelectItems\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toFloat32\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 34,\n                      \"NameEnd\": 43\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 43,\n                      \"RightParenPos\": 55,\n                      \"Items\": {\n                        \"ListPos\": 44,\n                        \"ListEnd\": 55,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"LeftExpr\": {\n                                \"Name\": \"number\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 44,\n                                \"NameEnd\": 50\n                              },\n                              \"Operation\": \"%\",\n                              \"RightExpr\": {\n                                \"NumPos\": 53,\n                                \"NumEnd\": 55,\n                                \"Literal\": \"10\",\n                                \"Base\": 10\n                              },\n                              \"HasGlobal\": false,\n                              \"HasNot\": false\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"n\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 60,\n                    \"NameEnd\": 61\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 64,\n                    \"LiteralEnd\": 72,\n                    \"Literal\": \"original\"\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"source\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 77,\n                    \"NameEnd\": 83\n                  }\n                }\n              ],\n              \"From\": {\n                \"FromPos\": 87,\n                \"Expr\": {\n                  \"Table\": {\n                    \"TablePos\": 92,\n                    \"TableEnd\": 102,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"numbers\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 92,\n                        \"NameEnd\": 99\n                      },\n                      \"Args\": {\n                        \"LeftParenPos\": 99,\n                        \"RightParenPos\": 102,\n                        \"Args\": [\n                          {\n                            \"NumPos\": 100,\n                            \"NumEnd\": 102,\n                            \"Literal\": \"10\",\n                            \"Base\": 10\n                          }\n                        ]\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 102,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                }\n              },\n              \"Window\": null,\n              \"Prewhere\": null,\n              \"Where\": {\n                \"WherePos\": 104,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"number\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 110,\n                      \"NameEnd\": 116\n                    },\n                    \"Operation\": \"%\",\n                    \"RightExpr\": {\n                      \"NumPos\": 119,\n                      \"NumEnd\": 120,\n                      \"Literal\": \"3\",\n                      \"Base\": 10\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Operation\": \"=\",\n                  \"RightExpr\": {\n                    \"NumPos\": 123,\n                    \"NumEnd\": 124,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                }\n              },\n              \"GroupBy\": null,\n              \"WithTotal\": false,\n              \"Having\": null,\n              \"OrderBy\": null,\n              \"LimitBy\": null,\n              \"Limit\": null,\n              \"Settings\": null,\n              \"Format\": null,\n              \"UnionAll\": null,\n              \"UnionDistinct\": null,\n              \"Except\": null\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 124,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 127,\n      \"ListEnd\": 151,\n      \"Items\": [\n        {\n          \"OrderPos\": 127,\n          \"Expr\": {\n            \"Name\": \"n\",\n            \"QuoteType\": 1,\n            \"NamePos\": 136,\n            \"NameEnd\": 137\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": {\n            \"FillPos\": 147,\n            \"From\": null,\n            \"To\": null,\n            \"Step\": null,\n            \"Staleness\": null\n          }\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_with_fill_from_to.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 171,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"n\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 8\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"source\",\n          \"QuoteType\": 1,\n          \"NamePos\": 10,\n          \"NameEnd\": 16\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 17,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 22,\n          \"TableEnd\": 124,\n          \"Alias\": null,\n          \"Expr\": {\n            \"HasParen\": true,\n            \"Select\": {\n              \"SelectPos\": 27,\n              \"StatementEnd\": 124,\n              \"With\": null,\n              \"Top\": null,\n              \"HasDistinct\": false,\n              \"DistinctOn\": null,\n              \"SelectItems\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toFloat32\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 34,\n                      \"NameEnd\": 43\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 43,\n                      \"RightParenPos\": 55,\n                      \"Items\": {\n                        \"ListPos\": 44,\n                        \"ListEnd\": 55,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"LeftExpr\": {\n                                \"Name\": \"number\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 44,\n                                \"NameEnd\": 50\n                              },\n                              \"Operation\": \"%\",\n                              \"RightExpr\": {\n                                \"NumPos\": 53,\n                                \"NumEnd\": 55,\n                                \"Literal\": \"10\",\n                                \"Base\": 10\n                              },\n                              \"HasGlobal\": false,\n                              \"HasNot\": false\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"n\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 60,\n                    \"NameEnd\": 61\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 64,\n                    \"LiteralEnd\": 72,\n                    \"Literal\": \"original\"\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"source\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 77,\n                    \"NameEnd\": 83\n                  }\n                }\n              ],\n              \"From\": {\n                \"FromPos\": 87,\n                \"Expr\": {\n                  \"Table\": {\n                    \"TablePos\": 92,\n                    \"TableEnd\": 102,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"numbers\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 92,\n                        \"NameEnd\": 99\n                      },\n                      \"Args\": {\n                        \"LeftParenPos\": 99,\n                        \"RightParenPos\": 102,\n                        \"Args\": [\n                          {\n                            \"NumPos\": 100,\n                            \"NumEnd\": 102,\n                            \"Literal\": \"10\",\n                            \"Base\": 10\n                          }\n                        ]\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 102,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                }\n              },\n              \"Window\": null,\n              \"Prewhere\": null,\n              \"Where\": {\n                \"WherePos\": 104,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"number\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 110,\n                      \"NameEnd\": 116\n                    },\n                    \"Operation\": \"%\",\n                    \"RightExpr\": {\n                      \"NumPos\": 119,\n                      \"NumEnd\": 120,\n                      \"Literal\": \"3\",\n                      \"Base\": 10\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Operation\": \"=\",\n                  \"RightExpr\": {\n                    \"NumPos\": 123,\n                    \"NumEnd\": 124,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                }\n              },\n              \"GroupBy\": null,\n              \"WithTotal\": false,\n              \"Having\": null,\n              \"OrderBy\": null,\n              \"LimitBy\": null,\n              \"Limit\": null,\n              \"Settings\": null,\n              \"Format\": null,\n              \"UnionAll\": null,\n              \"UnionDistinct\": null,\n              \"Except\": null\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 124,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 127,\n      \"ListEnd\": 171,\n      \"Items\": [\n        {\n          \"OrderPos\": 127,\n          \"Expr\": {\n            \"Name\": \"n\",\n            \"QuoteType\": 1,\n            \"NamePos\": 136,\n            \"NameEnd\": 137\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": {\n            \"FillPos\": 148,\n            \"From\": {\n              \"NumPos\": 148,\n              \"NumEnd\": 154,\n              \"Literal\": \"0\",\n              \"Base\": 10\n            },\n            \"To\": {\n              \"NumPos\": 148,\n              \"NumEnd\": 162,\n              \"Literal\": \"5.51\",\n              \"Base\": 10\n            },\n            \"Step\": {\n              \"NumPos\": 148,\n              \"NumEnd\": 171,\n              \"Literal\": \"0.5\",\n              \"Base\": 10\n            },\n            \"Staleness\": null\n          }\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_with_fill_interpolate.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 228,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"n\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 8\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"source\",\n          \"QuoteType\": 1,\n          \"NamePos\": 10,\n          \"NameEnd\": 16\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"inter\",\n          \"QuoteType\": 1,\n          \"NamePos\": 18,\n          \"NameEnd\": 23\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 24,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 29,\n          \"TableEnd\": 148,\n          \"Alias\": null,\n          \"Expr\": {\n            \"HasParen\": true,\n            \"Select\": {\n              \"SelectPos\": 34,\n              \"StatementEnd\": 148,\n              \"With\": null,\n              \"Top\": null,\n              \"HasDistinct\": false,\n              \"DistinctOn\": null,\n              \"SelectItems\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toFloat32\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 41,\n                      \"NameEnd\": 50\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 50,\n                      \"RightParenPos\": 62,\n                      \"Items\": {\n                        \"ListPos\": 51,\n                        \"ListEnd\": 62,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"LeftExpr\": {\n                                \"Name\": \"number\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 51,\n                                \"NameEnd\": 57\n                              },\n                              \"Operation\": \"%\",\n                              \"RightExpr\": {\n                                \"NumPos\": 60,\n                                \"NumEnd\": 62,\n                                \"Literal\": \"10\",\n                                \"Base\": 10\n                              },\n                              \"HasGlobal\": false,\n                              \"HasNot\": false\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"n\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 67,\n                    \"NameEnd\": 68\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 71,\n                    \"LiteralEnd\": 79,\n                    \"Literal\": \"original\"\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"source\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 84,\n                    \"NameEnd\": 90\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"number\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 92,\n                    \"NameEnd\": 98\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"inter\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 102,\n                    \"NameEnd\": 107\n                  }\n                }\n              ],\n              \"From\": {\n                \"FromPos\": 111,\n                \"Expr\": {\n                  \"Table\": {\n                    \"TablePos\": 116,\n                    \"TableEnd\": 126,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"numbers\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 116,\n                        \"NameEnd\": 123\n                      },\n                      \"Args\": {\n                        \"LeftParenPos\": 123,\n                        \"RightParenPos\": 126,\n                        \"Args\": [\n                          {\n                            \"NumPos\": 124,\n                            \"NumEnd\": 126,\n                            \"Literal\": \"10\",\n                            \"Base\": 10\n                          }\n                        ]\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 126,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                }\n              },\n              \"Window\": null,\n              \"Prewhere\": null,\n              \"Where\": {\n                \"WherePos\": 128,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"number\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 134,\n                      \"NameEnd\": 140\n                    },\n                    \"Operation\": \"%\",\n                    \"RightExpr\": {\n                      \"NumPos\": 143,\n                      \"NumEnd\": 144,\n                      \"Literal\": \"3\",\n                      \"Base\": 10\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Operation\": \"=\",\n                  \"RightExpr\": {\n                    \"NumPos\": 147,\n                    \"NumEnd\": 148,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                }\n              },\n              \"GroupBy\": null,\n              \"WithTotal\": false,\n              \"Having\": null,\n              \"OrderBy\": null,\n              \"LimitBy\": null,\n              \"Limit\": null,\n              \"Settings\": null,\n              \"Format\": null,\n              \"UnionAll\": null,\n              \"UnionDistinct\": null,\n              \"Except\": null\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 148,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 151,\n      \"ListEnd\": 228,\n      \"Items\": [\n        {\n          \"OrderPos\": 151,\n          \"Expr\": {\n            \"Name\": \"n\",\n            \"QuoteType\": 1,\n            \"NamePos\": 160,\n            \"NameEnd\": 161\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": {\n            \"FillPos\": 172,\n            \"From\": {\n              \"NumPos\": 172,\n              \"NumEnd\": 178,\n              \"Literal\": \"0\",\n              \"Base\": 10\n            },\n            \"To\": {\n              \"NumPos\": 172,\n              \"NumEnd\": 186,\n              \"Literal\": \"5.51\",\n              \"Base\": 10\n            },\n            \"Step\": {\n              \"NumPos\": 172,\n              \"NumEnd\": 195,\n              \"Literal\": \"0.5\",\n              \"Base\": 10\n            },\n            \"Staleness\": null\n          }\n        }\n      ],\n      \"Interpolate\": {\n        \"InterpolatePos\": 196,\n        \"ListEnd\": 228,\n        \"Items\": [\n          {\n            \"Column\": {\n              \"Name\": \"inter\",\n              \"QuoteType\": 1,\n              \"NamePos\": 209,\n              \"NameEnd\": 214\n            },\n            \"Expr\": {\n              \"LeftExpr\": {\n                \"Name\": \"inter\",\n                \"QuoteType\": 1,\n                \"NamePos\": 218,\n                \"NameEnd\": 223\n              },\n              \"Operation\": \"+\",\n              \"RightExpr\": {\n                \"NumPos\": 226,\n                \"NumEnd\": 227,\n                \"Literal\": \"1\",\n                \"Base\": 10\n              },\n              \"HasGlobal\": false,\n              \"HasNot\": false\n            }\n          }\n        ]\n      }\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_with_fill_interpolate_no_columns.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 173,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"n\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 8\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 10,\n          \"NameEnd\": 15\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 16,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 21,\n          \"TableEnd\": 118,\n          \"Alias\": null,\n          \"Expr\": {\n            \"HasParen\": true,\n            \"Select\": {\n              \"SelectPos\": 26,\n              \"StatementEnd\": 118,\n              \"With\": null,\n              \"Top\": null,\n              \"HasDistinct\": false,\n              \"DistinctOn\": null,\n              \"SelectItems\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toFloat32\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 33,\n                      \"NameEnd\": 42\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 42,\n                      \"RightParenPos\": 54,\n                      \"Items\": {\n                        \"ListPos\": 43,\n                        \"ListEnd\": 54,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"LeftExpr\": {\n                                \"Name\": \"number\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 43,\n                                \"NameEnd\": 49\n                              },\n                              \"Operation\": \"%\",\n                              \"RightExpr\": {\n                                \"NumPos\": 52,\n                                \"NumEnd\": 54,\n                                \"Literal\": \"10\",\n                                \"Base\": 10\n                              },\n                              \"HasGlobal\": false,\n                              \"HasNot\": false\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"n\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 59,\n                    \"NameEnd\": 60\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"number\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 62,\n                    \"NameEnd\": 68\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"value\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 72,\n                    \"NameEnd\": 77\n                  }\n                }\n              ],\n              \"From\": {\n                \"FromPos\": 81,\n                \"Expr\": {\n                  \"Table\": {\n                    \"TablePos\": 86,\n                    \"TableEnd\": 96,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"numbers\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 86,\n                        \"NameEnd\": 93\n                      },\n                      \"Args\": {\n                        \"LeftParenPos\": 93,\n                        \"RightParenPos\": 96,\n                        \"Args\": [\n                          {\n                            \"NumPos\": 94,\n                            \"NumEnd\": 96,\n                            \"Literal\": \"10\",\n                            \"Base\": 10\n                          }\n                        ]\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 96,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                }\n              },\n              \"Window\": null,\n              \"Prewhere\": null,\n              \"Where\": {\n                \"WherePos\": 98,\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"number\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 104,\n                      \"NameEnd\": 110\n                    },\n                    \"Operation\": \"%\",\n                    \"RightExpr\": {\n                      \"NumPos\": 113,\n                      \"NumEnd\": 114,\n                      \"Literal\": \"3\",\n                      \"Base\": 10\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Operation\": \"=\",\n                  \"RightExpr\": {\n                    \"NumPos\": 117,\n                    \"NumEnd\": 118,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                }\n              },\n              \"GroupBy\": null,\n              \"WithTotal\": false,\n              \"Having\": null,\n              \"OrderBy\": null,\n              \"LimitBy\": null,\n              \"Limit\": null,\n              \"Settings\": null,\n              \"Format\": null,\n              \"UnionAll\": null,\n              \"UnionDistinct\": null,\n              \"Except\": null\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 118,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 121,\n      \"ListEnd\": 173,\n      \"Items\": [\n        {\n          \"OrderPos\": 121,\n          \"Expr\": {\n            \"Name\": \"n\",\n            \"QuoteType\": 1,\n            \"NamePos\": 130,\n            \"NameEnd\": 131\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": {\n            \"FillPos\": 142,\n            \"From\": {\n              \"NumPos\": 142,\n              \"NumEnd\": 148,\n              \"Literal\": \"0\",\n              \"Base\": 10\n            },\n            \"To\": {\n              \"NumPos\": 142,\n              \"NumEnd\": 154,\n              \"Literal\": \"10\",\n              \"Base\": 10\n            },\n            \"Step\": {\n              \"NumPos\": 142,\n              \"NumEnd\": 161,\n              \"Literal\": \"1\",\n              \"Base\": 10\n            },\n            \"Staleness\": null\n          }\n        }\n      ],\n      \"Interpolate\": {\n        \"InterpolatePos\": 162,\n        \"ListEnd\": 173,\n        \"Items\": null\n      }\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_with_fill_staleness.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 137,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"number\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 13\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"key\",\n          \"QuoteType\": 1,\n          \"NamePos\": 17,\n          \"NameEnd\": 20\n        }\n      },\n      {\n        \"Expr\": {\n          \"LeftExpr\": {\n            \"NumPos\": 22,\n            \"NumEnd\": 23,\n            \"Literal\": \"5\",\n            \"Base\": 10\n          },\n          \"Operation\": \"*\",\n          \"RightExpr\": {\n            \"Name\": \"number\",\n            \"QuoteType\": 1,\n            \"NamePos\": 26,\n            \"NameEnd\": 32\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 33,\n          \"NameEnd\": 38\n        }\n      },\n      {\n        \"Expr\": {\n          \"LiteralPos\": 41,\n          \"LiteralEnd\": 49,\n          \"Literal\": \"original\"\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"source\",\n          \"QuoteType\": 1,\n          \"NamePos\": 54,\n          \"NameEnd\": 60\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 61,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 66,\n          \"TableEnd\": 76,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Name\": {\n              \"Name\": \"numbers\",\n              \"QuoteType\": 1,\n              \"NamePos\": 66,\n              \"NameEnd\": 73\n            },\n            \"Args\": {\n              \"LeftParenPos\": 73,\n              \"RightParenPos\": 76,\n              \"Args\": [\n                {\n                  \"NumPos\": 74,\n                  \"NumEnd\": 76,\n                  \"Literal\": \"16\",\n                  \"Base\": 10\n                }\n              ]\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 76,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 78,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LeftParenPos\": 84,\n          \"RightParenPos\": 95,\n          \"Items\": {\n            \"ListPos\": 85,\n            \"ListEnd\": 95,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"LeftExpr\": {\n                    \"Name\": \"number\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 85,\n                    \"NameEnd\": 91\n                  },\n                  \"Operation\": \"%\",\n                  \"RightExpr\": {\n                    \"NumPos\": 94,\n                    \"NumEnd\": 95,\n                    \"Literal\": \"5\",\n                    \"Base\": 10\n                  },\n                  \"HasGlobal\": false,\n                  \"HasNot\": false\n                },\n                \"Alias\": null\n              }\n            ]\n          },\n          \"ColumnArgList\": null\n        },\n        \"Operation\": \"==\",\n        \"RightExpr\": {\n          \"NumPos\": 100,\n          \"NumEnd\": 101,\n          \"Literal\": \"0\",\n          \"Base\": 10\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 102,\n      \"ListEnd\": 137,\n      \"Items\": [\n        {\n          \"OrderPos\": 102,\n          \"Expr\": {\n            \"Name\": \"key\",\n            \"QuoteType\": 1,\n            \"NamePos\": 111,\n            \"NameEnd\": 114\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": {\n            \"FillPos\": 125,\n            \"From\": null,\n            \"To\": null,\n            \"Step\": null,\n            \"Staleness\": {\n              \"NumPos\": 125,\n              \"NumEnd\": 137,\n              \"Literal\": \"11\",\n              \"Base\": 10\n            }\n          }\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_order_by_with_fill_step.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 170,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"date\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 11\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 13,\n          \"NameEnd\": 18\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 19,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 24,\n          \"TableEnd\": 123,\n          \"Alias\": null,\n          \"Expr\": {\n            \"HasParen\": true,\n            \"Select\": {\n              \"SelectPos\": 30,\n              \"StatementEnd\": 123,\n              \"With\": null,\n              \"Top\": null,\n              \"HasDistinct\": false,\n              \"DistinctOn\": null,\n              \"SelectItems\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Name\": {\n                        \"Name\": \"toDate\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 37,\n                        \"NameEnd\": 43\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 43,\n                        \"RightParenPos\": 56,\n                        \"Items\": {\n                          \"ListPos\": 45,\n                          \"ListEnd\": 55,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 45,\n                                \"LiteralEnd\": 55,\n                                \"Literal\": \"2020-01-01\"\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Operation\": \"+\",\n                    \"RightExpr\": {\n                      \"IntervalPos\": 60,\n                      \"Expr\": {\n                        \"Name\": \"number\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 69,\n                        \"NameEnd\": 75\n                      },\n                      \"Unit\": {\n                        \"Name\": \"DAY\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 76,\n                        \"NameEnd\": 79\n                      }\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"date\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 83,\n                    \"NameEnd\": 87\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"number\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 89,\n                    \"NameEnd\": 95\n                  },\n                  \"Modifiers\": [],\n                  \"Alias\": {\n                    \"Name\": \"value\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 99,\n                    \"NameEnd\": 104\n                  }\n                }\n              ],\n              \"From\": {\n                \"FromPos\": 109,\n                \"Expr\": {\n                  \"Table\": {\n                    \"TablePos\": 114,\n                    \"TableEnd\": 123,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"numbers\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 114,\n                        \"NameEnd\": 121\n                      },\n                      \"Args\": {\n                        \"LeftParenPos\": 121,\n                        \"RightParenPos\": 123,\n                        \"Args\": [\n                          {\n                            \"NumPos\": 122,\n                            \"NumEnd\": 123,\n                            \"Literal\": \"5\",\n                            \"Base\": 10\n                          }\n                        ]\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 123,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                }\n              },\n              \"Window\": null,\n              \"Prewhere\": null,\n              \"Where\": null,\n              \"GroupBy\": null,\n              \"WithTotal\": false,\n              \"Having\": null,\n              \"OrderBy\": null,\n              \"LimitBy\": null,\n              \"Limit\": null,\n              \"Settings\": null,\n              \"Format\": null,\n              \"UnionAll\": null,\n              \"UnionDistinct\": null,\n              \"Except\": null\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 123,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 127,\n      \"ListEnd\": 170,\n      \"Items\": [\n        {\n          \"OrderPos\": 127,\n          \"Expr\": {\n            \"Name\": \"date\",\n            \"QuoteType\": 1,\n            \"NamePos\": 136,\n            \"NameEnd\": 140\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": {\n            \"FillPos\": 151,\n            \"From\": null,\n            \"To\": null,\n            \"Step\": {\n              \"IntervalPos\": 156,\n              \"Expr\": {\n                \"NumPos\": 165,\n                \"NumEnd\": 166,\n                \"Literal\": \"1\",\n                \"Base\": 10\n              },\n              \"Unit\": {\n                \"Name\": \"DAY\",\n                \"QuoteType\": 1,\n                \"NamePos\": 167,\n                \"NameEnd\": 170\n              }\n            },\n            \"Staleness\": null\n          }\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 277,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"f0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 11,\n          \"NameEnd\": 13\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"coalesce\",\n            \"QuoteType\": 1,\n            \"NamePos\": 15,\n            \"NameEnd\": 23\n          },\n          \"Params\": {\n            \"LeftParenPos\": 23,\n            \"RightParenPos\": 30,\n            \"Items\": {\n              \"ListPos\": 24,\n              \"ListEnd\": 30,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"f1\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 24,\n                    \"NameEnd\": 26\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"f2\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 28,\n                    \"NameEnd\": 30\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"f3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 35,\n          \"NameEnd\": 37\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"row_number\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 49\n            },\n            \"Params\": {\n              \"LeftParenPos\": 49,\n              \"RightParenPos\": 50,\n              \"Items\": {\n                \"ListPos\": 50,\n                \"ListEnd\": 50,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 52,\n          \"OverExpr\": {\n            \"LeftParenPos\": 57,\n            \"RightParenPos\": 89,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 57,\n              \"Expr\": {\n                \"ListPos\": 71,\n                \"ListEnd\": 73,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 71,\n                      \"NameEnd\": 73\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 74,\n              \"ListEnd\": 85,\n              \"Items\": [\n                {\n                  \"OrderPos\": 74,\n                  \"Expr\": {\n                    \"Name\": \"f1\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 83,\n                    \"NameEnd\": 85\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"ASC\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rn\",\n          \"QuoteType\": 1,\n          \"NamePos\": 94,\n          \"NameEnd\": 96\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 97,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 102,\n          \"TableEnd\": 119,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": {\n              \"Name\": \"test\",\n              \"QuoteType\": 1,\n              \"NamePos\": 102,\n              \"NameEnd\": 106\n            },\n            \"Table\": {\n              \"Name\": \"events_local\",\n              \"QuoteType\": 1,\n              \"NamePos\": 107,\n              \"NameEnd\": 119\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 119,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 120,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LeftExpr\": {\n            \"LeftExpr\": {\n              \"LeftParenPos\": 126,\n              \"RightParenPos\": 155,\n              \"Items\": {\n                \"ListPos\": 127,\n                \"ListEnd\": 154,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Name\": \"f0\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 127,\n                        \"NameEnd\": 129\n                      },\n                      \"Operation\": \"IN\",\n                      \"RightExpr\": {\n                        \"LeftParenPos\": 133,\n                        \"RightParenPos\": 154,\n                        \"Items\": {\n                          \"ListPos\": 135,\n                          \"ListEnd\": 153,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 135,\n                                \"LiteralEnd\": 138,\n                                \"Literal\": \"foo\"\n                              },\n                              \"Alias\": null\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 142,\n                                \"LiteralEnd\": 145,\n                                \"Literal\": \"bar\"\n                              },\n                              \"Alias\": null\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 149,\n                                \"LiteralEnd\": 153,\n                                \"Literal\": \"test\"\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Operation\": \"AND\",\n            \"RightExpr\": {\n              \"LeftParenPos\": 161,\n              \"RightParenPos\": 176,\n              \"Items\": {\n                \"ListPos\": 162,\n                \"ListEnd\": 175,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Name\": \"f1\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 162,\n                        \"NameEnd\": 164\n                      },\n                      \"Operation\": \"=\",\n                      \"RightExpr\": {\n                        \"LiteralPos\": 168,\n                        \"LiteralEnd\": 175,\n                        \"Literal\": \"testing\"\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"Operation\": \"AND\",\n          \"RightExpr\": {\n            \"LeftParenPos\": 182,\n            \"RightParenPos\": 205,\n            \"Items\": {\n              \"ListPos\": 183,\n              \"ListEnd\": 204,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 183,\n                      \"NameEnd\": 185\n                    },\n                    \"Operation\": \"NOT LIKE\",\n                    \"RightExpr\": {\n                      \"LiteralPos\": 196,\n                      \"LiteralEnd\": 204,\n                      \"Literal\": \"testing2\"\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Operation\": \"AND\",\n        \"RightExpr\": {\n          \"LeftExpr\": {\n            \"Name\": \"f3\",\n            \"QuoteType\": 1,\n            \"NamePos\": 211,\n            \"NameEnd\": 213\n          },\n          \"Operation\": \"NOT IN\",\n          \"RightExpr\": {\n            \"LeftParenPos\": 221,\n            \"RightParenPos\": 235,\n            \"Items\": {\n              \"ListPos\": 223,\n              \"ListEnd\": 234,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 223,\n                    \"LiteralEnd\": 224,\n                    \"Literal\": \"a\"\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 228,\n                    \"LiteralEnd\": 229,\n                    \"Literal\": \"b\"\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 233,\n                    \"LiteralEnd\": 234,\n                    \"Literal\": \"c\"\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": {\n      \"GroupByPos\": 239,\n      \"GroupByEnd\": 258,\n      \"AggregateType\": \"\",\n      \"Expr\": {\n        \"ListPos\": 248,\n        \"ListEnd\": 256,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 248,\n              \"NameEnd\": 250\n            },\n            \"Alias\": null\n          },\n          {\n            \"Expr\": {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 254,\n              \"NameEnd\": 256\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"WithCube\": false,\n      \"WithRollup\": false,\n      \"WithTotals\": false\n    },\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": {\n      \"Limit\": {\n        \"LimitPos\": 258,\n        \"Limit\": {\n          \"NumPos\": 269,\n          \"NumEnd\": 271,\n          \"Literal\": \"10\",\n          \"Base\": 10\n        },\n        \"Offset\": {\n          \"NumPos\": 264,\n          \"NumEnd\": 267,\n          \"Literal\": \"100\",\n          \"Base\": 10\n        }\n      },\n      \"ByExpr\": {\n        \"ListPos\": 275,\n        \"ListEnd\": 277,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"Name\": \"f0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 275,\n              \"NameEnd\": 277\n            },\n            \"Alias\": null\n          }\n        ]\n      }\n    },\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_field_alias.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 48,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"field0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 13\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"field1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 15,\n          \"NameEnd\": 21\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"x\",\n          \"QuoteType\": 1,\n          \"NamePos\": 25,\n          \"NameEnd\": 26\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"field2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 28,\n          \"NameEnd\": 34\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"y\",\n          \"QuoteType\": 1,\n          \"NamePos\": 35,\n          \"NameEnd\": 36\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 37,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 42,\n          \"TableEnd\": 48,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"events\",\n              \"QuoteType\": 1,\n              \"NamePos\": 42,\n              \"NameEnd\": 48\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 48,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_bracket.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 66,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"arrayConcat\",\n            \"QuoteType\": 1,\n            \"NamePos\": 7,\n            \"NameEnd\": 18\n          },\n          \"Params\": {\n            \"LeftParenPos\": 18,\n            \"RightParenPos\": 41,\n            \"Items\": {\n              \"ListPos\": 19,\n              \"ListEnd\": 40,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftBracketPos\": 19,\n                    \"RightBracketPos\": 24,\n                    \"Items\": {\n                      \"ListPos\": 20,\n                      \"ListEnd\": 24,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"NumPos\": 20,\n                            \"NumEnd\": 21,\n                            \"Literal\": \"1\",\n                            \"Base\": 10\n                          },\n                          \"Alias\": null\n                        },\n                        {\n                          \"Expr\": {\n                            \"NumPos\": 23,\n                            \"NumEnd\": 24,\n                            \"Literal\": \"2\",\n                            \"Base\": 10\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    }\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"LeftBracketPos\": 27,\n                    \"RightBracketPos\": 32,\n                    \"Items\": {\n                      \"ListPos\": 28,\n                      \"ListEnd\": 32,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"NumPos\": 28,\n                            \"NumEnd\": 29,\n                            \"Literal\": \"3\",\n                            \"Base\": 10\n                          },\n                          \"Alias\": null\n                        },\n                        {\n                          \"Expr\": {\n                            \"NumPos\": 31,\n                            \"NumEnd\": 32,\n                            \"Literal\": \"4\",\n                            \"Base\": 10\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    }\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"LeftBracketPos\": 35,\n                    \"RightBracketPos\": 40,\n                    \"Items\": {\n                      \"ListPos\": 36,\n                      \"ListEnd\": 40,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"NumPos\": 36,\n                            \"NumEnd\": 37,\n                            \"Literal\": \"5\",\n                            \"Base\": 10\n                          },\n                          \"Alias\": null\n                        },\n                        {\n                          \"Expr\": {\n                            \"NumPos\": 39,\n                            \"NumEnd\": 40,\n                            \"Literal\": \"6\",\n                            \"Base\": 10\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    }\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"res\",\n          \"QuoteType\": 1,\n          \"NamePos\": 46,\n          \"NameEnd\": 49\n        }\n      },\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"Name\": \"f1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 51,\n            \"NameEnd\": 53\n          },\n          \"Params\": {\n            \"LeftBracketPos\": 53,\n            \"RightBracketPos\": 59,\n            \"Items\": {\n              \"ListPos\": 55,\n              \"ListEnd\": 58,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"abc\",\n                    \"QuoteType\": 2,\n                    \"NamePos\": 55,\n                    \"NameEnd\": 58\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"f2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 64,\n          \"NameEnd\": 66\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_cte_with_column_aliases.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 133,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 24,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 9,\n          \"Expr\": {\n            \"Name\": {\n              \"Name\": \"test\",\n              \"QuoteType\": 1,\n              \"NamePos\": 9,\n              \"NameEnd\": 13\n            },\n            \"Params\": {\n              \"LeftParenPos\": 13,\n              \"RightParenPos\": 24,\n              \"Items\": {\n                \"ListPos\": 14,\n                \"ListEnd\": 24,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 14,\n                      \"NameEnd\": 16\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 18,\n                      \"NameEnd\": 20\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"f3\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 22,\n                      \"NameEnd\": 24\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"Alias\": {\n            \"SelectPos\": 30,\n            \"StatementEnd\": 58,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"f4\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 37,\n                  \"NameEnd\": 39\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"f5\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 41,\n                  \"NameEnd\": 43\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"f6\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 45,\n                  \"NameEnd\": 47\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              }\n            ],\n            \"From\": {\n              \"FromPos\": 48,\n              \"Expr\": {\n                \"Table\": {\n                  \"TablePos\": 53,\n                  \"TableEnd\": 58,\n                  \"Alias\": null,\n                  \"Expr\": {\n                    \"Database\": null,\n                    \"Table\": {\n                      \"Name\": \"sales\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 53,\n                      \"NameEnd\": 58\n                    }\n                  },\n                  \"HasFinal\": false\n                },\n                \"StatementEnd\": 58,\n                \"SampleRatio\": null,\n                \"HasFinal\": false\n              }\n            },\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"f1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 71,\n          \"NameEnd\": 73\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"new_f1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 77,\n          \"NameEnd\": 83\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 89,\n          \"NameEnd\": 91\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"new_f2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 95,\n          \"NameEnd\": 101\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 107,\n          \"NameEnd\": 109\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"new_f3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 113,\n          \"NameEnd\": 119\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 120,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 129,\n          \"TableEnd\": 133,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"test\",\n              \"QuoteType\": 1,\n              \"NamePos\": 129,\n              \"NameEnd\": 133\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 133,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_group_by_with_cube_totals.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 86,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"a\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 8\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"COUNT\",\n            \"QuoteType\": 1,\n            \"NamePos\": 10,\n            \"NameEnd\": 15\n          },\n          \"Params\": {\n            \"LeftParenPos\": 15,\n            \"RightParenPos\": 17,\n            \"Items\": {\n              \"ListPos\": 16,\n              \"ListEnd\": 17,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"b\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 16,\n                    \"NameEnd\": 17\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 19,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 24,\n          \"TableEnd\": 36,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"group_by_all\",\n              \"QuoteType\": 1,\n              \"NamePos\": 24,\n              \"NameEnd\": 36\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 36,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": {\n      \"GroupByPos\": 37,\n      \"GroupByEnd\": 76,\n      \"AggregateType\": \"CUBE\",\n      \"Expr\": {\n        \"LeftParenPos\": 50,\n        \"RightParenPos\": 52,\n        \"Items\": {\n          \"ListPos\": 51,\n          \"ListEnd\": 52,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"Name\": \"a\",\n                \"QuoteType\": 1,\n                \"NamePos\": 51,\n                \"NameEnd\": 52\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"WithCube\": true,\n      \"WithRollup\": false,\n      \"WithTotals\": true\n    },\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 76,\n      \"ListEnd\": 86,\n      \"Items\": [\n        {\n          \"OrderPos\": 76,\n          \"Expr\": {\n            \"Name\": \"a\",\n            \"QuoteType\": 1,\n            \"NamePos\": 85,\n            \"NameEnd\": 86\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": null\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_is_not_null.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 133,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"f0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 9\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 10,\n          \"NameEnd\": 12\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 13,\n          \"NameEnd\": 15\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 16,\n          \"NameEnd\": 18\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"a0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 22,\n          \"NameEnd\": 24\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 25,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 30,\n          \"TableEnd\": 47,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": {\n              \"Name\": \"test\",\n              \"QuoteType\": 1,\n              \"NamePos\": 30,\n              \"NameEnd\": 34\n            },\n            \"Table\": {\n              \"Name\": \"events_local\",\n              \"QuoteType\": 1,\n              \"NamePos\": 35,\n              \"NameEnd\": 47\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 47,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 48,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LeftExpr\": {\n            \"LeftExpr\": {\n              \"LeftParenPos\": 54,\n              \"RightParenPos\": 83,\n              \"Items\": {\n                \"ListPos\": 55,\n                \"ListEnd\": 82,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Name\": \"f0\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 55,\n                        \"NameEnd\": 57\n                      },\n                      \"Operation\": \"IN\",\n                      \"RightExpr\": {\n                        \"LeftParenPos\": 61,\n                        \"RightParenPos\": 82,\n                        \"Items\": {\n                          \"ListPos\": 63,\n                          \"ListEnd\": 81,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 63,\n                                \"LiteralEnd\": 66,\n                                \"Literal\": \"foo\"\n                              },\n                              \"Alias\": null\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 70,\n                                \"LiteralEnd\": 73,\n                                \"Literal\": \"bar\"\n                              },\n                              \"Alias\": null\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 77,\n                                \"LiteralEnd\": 81,\n                                \"Literal\": \"test\"\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Operation\": \"AND\",\n            \"RightExpr\": {\n              \"LeftParenPos\": 91,\n              \"RightParenPos\": 106,\n              \"Items\": {\n                \"ListPos\": 92,\n                \"ListEnd\": 105,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Name\": \"f1\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 92,\n                        \"NameEnd\": 94\n                      },\n                      \"Operation\": \"=\",\n                      \"RightExpr\": {\n                        \"LiteralPos\": 98,\n                        \"LiteralEnd\": 105,\n                        \"Literal\": \"testing\"\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"HasGlobal\": false,\n            \"HasNot\": false\n          },\n          \"Operation\": \"AND\",\n          \"RightExpr\": {\n            \"IsPos\": 127,\n            \"Expr\": {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 114,\n              \"NameEnd\": 116\n            }\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Operation\": \"AND\",\n        \"RightExpr\": {\n          \"IsPos\": 145,\n          \"Expr\": {\n            \"Name\": \"f3\",\n            \"QuoteType\": 1,\n            \"NamePos\": 131,\n            \"NameEnd\": 133\n          }\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_is_null.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 112,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"f0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 9\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 10,\n          \"NameEnd\": 12\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 13,\n          \"NameEnd\": 15\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"f3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 16,\n          \"NameEnd\": 18\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"a0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 22,\n          \"NameEnd\": 24\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 25,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 30,\n          \"TableEnd\": 47,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": {\n              \"Name\": \"test\",\n              \"QuoteType\": 1,\n              \"NamePos\": 30,\n              \"NameEnd\": 34\n            },\n            \"Table\": {\n              \"Name\": \"events_local\",\n              \"QuoteType\": 1,\n              \"NamePos\": 35,\n              \"NameEnd\": 47\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 47,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 48,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LeftExpr\": {\n            \"LeftParenPos\": 54,\n            \"RightParenPos\": 83,\n            \"Items\": {\n              \"ListPos\": 55,\n              \"ListEnd\": 82,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"f0\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 55,\n                      \"NameEnd\": 57\n                    },\n                    \"Operation\": \"IN\",\n                    \"RightExpr\": {\n                      \"LeftParenPos\": 61,\n                      \"RightParenPos\": 82,\n                      \"Items\": {\n                        \"ListPos\": 63,\n                        \"ListEnd\": 81,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"LiteralPos\": 63,\n                              \"LiteralEnd\": 66,\n                              \"Literal\": \"foo\"\n                            },\n                            \"Alias\": null\n                          },\n                          {\n                            \"Expr\": {\n                              \"LiteralPos\": 70,\n                              \"LiteralEnd\": 73,\n                              \"Literal\": \"bar\"\n                            },\n                            \"Alias\": null\n                          },\n                          {\n                            \"Expr\": {\n                              \"LiteralPos\": 77,\n                              \"LiteralEnd\": 81,\n                              \"Literal\": \"test\"\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          },\n          \"Operation\": \"AND\",\n          \"RightExpr\": {\n            \"LeftParenPos\": 89,\n            \"RightParenPos\": 104,\n            \"Items\": {\n              \"ListPos\": 90,\n              \"ListEnd\": 103,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Name\": \"f1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 90,\n                      \"NameEnd\": 92\n                    },\n                    \"Operation\": \"=\",\n                    \"RightExpr\": {\n                      \"LiteralPos\": 96,\n                      \"LiteralEnd\": 103,\n                      \"Literal\": \"testing\"\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Operation\": \"AND\",\n        \"RightExpr\": {\n          \"IsPos\": 120,\n          \"Expr\": {\n            \"Name\": \"f2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 110,\n            \"NameEnd\": 112\n          }\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_limit.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 16,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 7,\n          \"NumEnd\": 8,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": {\n      \"LimitPos\": 9,\n      \"Limit\": {\n        \"NumPos\": 15,\n        \"NumEnd\": 16,\n        \"Literal\": \"1\",\n        \"Base\": 10\n      },\n      \"Offset\": null\n    },\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 18,\n    \"StatementEnd\": 43,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 25,\n          \"NumEnd\": 26,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": {\n      \"LimitPos\": 27,\n      \"Limit\": {\n        \"NumPos\": 33,\n        \"NumEnd\": 34,\n        \"Literal\": \"1\",\n        \"Base\": 10\n      },\n      \"Offset\": {\n        \"NumPos\": 42,\n        \"NumEnd\": 43,\n        \"Literal\": \"0\",\n        \"Base\": 10\n      }\n    },\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 45,\n    \"StatementEnd\": 62,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 52,\n          \"NumEnd\": 53,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": {\n      \"LimitPos\": 54,\n      \"Limit\": null,\n      \"Offset\": {\n        \"NumPos\": 61,\n        \"NumEnd\": 62,\n        \"Literal\": \"0\",\n        \"Base\": 10\n      }\n    },\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_top_clause.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 38,\n    \"With\": null,\n    \"Top\": {\n      \"TopPos\": 7,\n      \"TopEnd\": 13,\n      \"Number\": {\n        \"NumPos\": 11,\n        \"NumEnd\": 13,\n        \"Literal\": \"10\",\n        \"Base\": 10\n      },\n      \"WithTies\": false\n    },\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"my_column\",\n          \"QuoteType\": 1,\n          \"NamePos\": 14,\n          \"NameEnd\": 23\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 24,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 29,\n          \"TableEnd\": 38,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"tableName\",\n              \"QuoteType\": 1,\n              \"NamePos\": 29,\n              \"NameEnd\": 38\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 38,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_simple_with_with_clause.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 134,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 46,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 9,\n          \"Expr\": {\n            \"Name\": \"cte1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 9,\n            \"NameEnd\": 13\n          },\n          \"Alias\": {\n            \"SelectPos\": 18,\n            \"StatementEnd\": 35,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"f1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 25,\n                  \"NameEnd\": 27\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              }\n            ],\n            \"From\": {\n              \"FromPos\": 28,\n              \"Expr\": {\n                \"Table\": {\n                  \"TablePos\": 33,\n                  \"TableEnd\": 35,\n                  \"Alias\": null,\n                  \"Expr\": {\n                    \"Database\": null,\n                    \"Table\": {\n                      \"Name\": \"t1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 33,\n                      \"NameEnd\": 35\n                    }\n                  },\n                  \"HasFinal\": false\n                },\n                \"StatementEnd\": 35,\n                \"SampleRatio\": null,\n                \"HasFinal\": false\n              }\n            },\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        },\n        {\n          \"CTEPos\": 42,\n          \"Expr\": {\n            \"Name\": \"cte2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 42,\n            \"NameEnd\": 46\n          },\n          \"Alias\": {\n            \"SelectPos\": 51,\n            \"StatementEnd\": 68,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"f2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 58,\n                  \"NameEnd\": 60\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              }\n            ],\n            \"From\": {\n              \"FromPos\": 61,\n              \"Expr\": {\n                \"Table\": {\n                  \"TablePos\": 66,\n                  \"TableEnd\": 68,\n                  \"Alias\": null,\n                  \"Expr\": {\n                    \"Database\": null,\n                    \"Table\": {\n                      \"Name\": \"t2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 66,\n                      \"NameEnd\": 68\n                    }\n                  },\n                  \"HasFinal\": false\n                },\n                \"StatementEnd\": 68,\n                \"SampleRatio\": null,\n                \"HasFinal\": false\n              }\n            },\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"cte1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 81,\n              \"NameEnd\": 85\n            },\n            {\n              \"Name\": \"f1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 86,\n              \"NameEnd\": 88\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"cte2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 94,\n              \"NameEnd\": 98\n            },\n            {\n              \"Name\": \"f2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 99,\n              \"NameEnd\": 101\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 107,\n              \"NameEnd\": 109\n            },\n            {\n              \"Name\": \"f3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 110,\n              \"NameEnd\": 112\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 113,\n      \"Expr\": {\n        \"JoinPos\": 122,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 122,\n            \"TableEnd\": 124,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"t3\",\n                \"QuoteType\": 1,\n                \"NamePos\": 122,\n                \"NameEnd\": 124\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 124,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 125,\n          \"Left\": {\n            \"Table\": {\n              \"TablePos\": 125,\n              \"TableEnd\": 129,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"cte1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 125,\n                  \"NameEnd\": 129\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 129,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Right\": {\n            \"Table\": {\n              \"TablePos\": 130,\n              \"TableEnd\": 134,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"cte2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 130,\n                  \"NameEnd\": 134\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 134,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Modifiers\": null,\n          \"Constraints\": null\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_table_alias_without_keyword.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 78,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 7,\n              \"NameEnd\": 9\n            },\n            {\n              \"Name\": \"Timestamp\",\n              \"QuoteType\": 1,\n              \"NamePos\": 10,\n              \"NameEnd\": 19\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 20,\n      \"Expr\": {\n        \"JoinPos\": 25,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 25,\n            \"TableEnd\": 36,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"my_table\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 25,\n                  \"NameEnd\": 33\n                }\n              },\n              \"AliasPos\": 34,\n              \"Alias\": {\n                \"Name\": \"t1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 34,\n                \"NameEnd\": 36\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 36,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 37,\n          \"Left\": {\n            \"Table\": {\n              \"TablePos\": 48,\n              \"TableEnd\": 65,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Expr\": {\n                  \"Database\": null,\n                  \"Table\": {\n                    \"Name\": \"my_other_table\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 48,\n                    \"NameEnd\": 62\n                  }\n                },\n                \"AliasPos\": 63,\n                \"Alias\": {\n                  \"Name\": \"t2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 63,\n                  \"NameEnd\": 65\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 65,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Right\": null,\n          \"Modifiers\": [\n            \"INNER\",\n            \"JOIN\"\n          ],\n          \"Constraints\": {\n            \"OnPos\": 66,\n            \"On\": {\n              \"ListPos\": 69,\n              \"ListEnd\": 78,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Fields\": [\n                        {\n                          \"Name\": \"t1\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 69,\n                          \"NameEnd\": 71\n                        },\n                        {\n                          \"Name\": \"a\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 72,\n                          \"NameEnd\": 73\n                        }\n                      ]\n                    },\n                    \"Operation\": \"=\",\n                    \"RightExpr\": {\n                      \"Fields\": [\n                        {\n                          \"Name\": \"t2\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 74,\n                          \"NameEnd\": 76\n                        },\n                        {\n                          \"Name\": \"b\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 77,\n                          \"NameEnd\": 78\n                        }\n                      ]\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_table_function_with_query.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 125,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 7,\n          \"NumEnd\": 8,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"HasParen\": true,\n          \"Select\": {\n            \"SelectPos\": 11,\n            \"StatementEnd\": 20,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"NumPos\": 18,\n                  \"NumEnd\": 20,\n                  \"Literal\": \"70\",\n                  \"Base\": 10\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"power\",\n          \"QuoteType\": 3,\n          \"NamePos\": 26,\n          \"NameEnd\": 31\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"number\",\n          \"QuoteType\": 1,\n          \"NamePos\": 34,\n          \"NameEnd\": 40\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 41,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 46,\n          \"TableEnd\": 125,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Name\": {\n              \"Name\": \"numbers\",\n              \"QuoteType\": 1,\n              \"NamePos\": 46,\n              \"NameEnd\": 53\n            },\n            \"Args\": {\n              \"LeftParenPos\": 53,\n              \"RightParenPos\": 125,\n              \"Args\": [\n                {\n                  \"Name\": {\n                    \"Name\": \"plus\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 59,\n                    \"NameEnd\": 63\n                  },\n                  \"Args\": {\n                    \"LeftParenPos\": 59,\n                    \"RightParenPos\": 123,\n                    \"Args\": [\n                      {\n                        \"Name\": {\n                          \"Name\": \"ifNull\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 73,\n                          \"NameEnd\": 79\n                        },\n                        \"Args\": {\n                          \"LeftParenPos\": 73,\n                          \"RightParenPos\": 117,\n                          \"Args\": [\n                            {\n                              \"HasParen\": true,\n                              \"Select\": {\n                                \"SelectPos\": 81,\n                                \"StatementEnd\": 105,\n                                \"With\": null,\n                                \"Top\": null,\n                                \"HasDistinct\": false,\n                                \"DistinctOn\": null,\n                                \"SelectItems\": [\n                                  {\n                                    \"Expr\": {\n                                      \"NumPos\": 88,\n                                      \"NumEnd\": 89,\n                                      \"Literal\": \"1\",\n                                      \"Base\": 10\n                                    },\n                                    \"Modifiers\": [],\n                                    \"Alias\": {\n                                      \"Name\": \"bin_count\",\n                                      \"QuoteType\": 1,\n                                      \"NamePos\": 93,\n                                      \"NameEnd\": 102\n                                    }\n                                  },\n                                  {\n                                    \"Expr\": {\n                                      \"NumPos\": 104,\n                                      \"NumEnd\": 105,\n                                      \"Literal\": \"1\",\n                                      \"Base\": 10\n                                    },\n                                    \"Modifiers\": [],\n                                    \"Alias\": null\n                                  }\n                                ],\n                                \"From\": null,\n                                \"Window\": null,\n                                \"Prewhere\": null,\n                                \"Where\": null,\n                                \"GroupBy\": null,\n                                \"WithTotal\": false,\n                                \"Having\": null,\n                                \"OrderBy\": null,\n                                \"LimitBy\": null,\n                                \"Limit\": null,\n                                \"Settings\": null,\n                                \"Format\": null,\n                                \"UnionAll\": null,\n                                \"UnionDistinct\": null,\n                                \"Except\": null\n                              }\n                            },\n                            {\n                              \"NumPos\": 116,\n                              \"NumEnd\": 117,\n                              \"Literal\": \"1\",\n                              \"Base\": 10\n                            }\n                          ]\n                        }\n                      }\n                    ]\n                  }\n                }\n              ]\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 125,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_when_condition.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 0,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"CasePos\": 7,\n          \"EndPos\": 0,\n          \"Expr\": null,\n          \"Whens\": [\n            {\n              \"WhenPos\": 12,\n              \"ThenPos\": 23,\n              \"When\": {\n                \"Name\": \"false\",\n                \"QuoteType\": 1,\n                \"NamePos\": 17,\n                \"NameEnd\": 22\n              },\n              \"Then\": {\n                \"LiteralPos\": 29,\n                \"LiteralEnd\": 34,\n                \"Literal\": \"hello\"\n              },\n              \"ElsePos\": 0,\n              \"Else\": null\n            }\n          ],\n          \"ElsePos\": 36,\n          \"Else\": {\n            \"LiteralPos\": 42,\n            \"LiteralEnd\": 47,\n            \"Literal\": \"world\"\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_window_comprehensive.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 167,\n    \"StatementEnd\": 4194,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 200,\n              \"NameEnd\": 203\n            },\n            \"Params\": {\n              \"LeftParenPos\": 203,\n              \"RightParenPos\": 205,\n              \"Items\": {\n                \"ListPos\": 204,\n                \"ListEnd\": 205,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 204,\n                      \"NameEnd\": 205\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 207,\n          \"OverExpr\": {\n            \"LeftParenPos\": 212,\n            \"RightParenPos\": 272,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 213,\n              \"ListEnd\": 223,\n              \"Items\": [\n                {\n                  \"OrderPos\": 213,\n                  \"Expr\": {\n                    \"Name\": \"y\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 222,\n                    \"NameEnd\": 223\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 224,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 237,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 257,\n                \"And\": {\n                  \"CurrentPos\": 261,\n                  \"RowEnd\": 273\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"running_total\",\n          \"QuoteType\": 1,\n          \"NamePos\": 317,\n          \"NameEnd\": 330\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"avg\",\n              \"QuoteType\": 1,\n              \"NamePos\": 336,\n              \"NameEnd\": 339\n            },\n            \"Params\": {\n              \"LeftParenPos\": 339,\n              \"RightParenPos\": 341,\n              \"Items\": {\n                \"ListPos\": 340,\n                \"ListEnd\": 341,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 340,\n                      \"NameEnd\": 341\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 351,\n          \"OverExpr\": {\n            \"LeftParenPos\": 356,\n            \"RightParenPos\": 424,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 356,\n              \"Expr\": {\n                \"ListPos\": 370,\n                \"ListEnd\": 371,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"z\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 370,\n                      \"NameEnd\": 371\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 372,\n              \"ListEnd\": 382,\n              \"Items\": [\n                {\n                  \"OrderPos\": 372,\n                  \"Expr\": {\n                    \"Name\": \"y\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 381,\n                    \"NameEnd\": 382\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 383,\n              \"Type\": \"RANGE\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 397,\n                    \"NumEnd\": 398,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 408,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 409,\n                \"And\": {\n                  \"Number\": {\n                    \"NumPos\": 413,\n                    \"NumEnd\": 414,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 424,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"avg_range1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 464,\n          \"NameEnd\": 474\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"row_number\",\n              \"QuoteType\": 1,\n              \"NamePos\": 517,\n              \"NameEnd\": 527\n            },\n            \"Params\": {\n              \"LeftParenPos\": 527,\n              \"RightParenPos\": 528,\n              \"Items\": {\n                \"ListPos\": 528,\n                \"ListEnd\": 528,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 530,\n          \"OverExpr\": {\n            \"Name\": \"w1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 535,\n            \"NameEnd\": 537\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rn_w1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 634,\n          \"NameEnd\": 639\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"rank\",\n              \"QuoteType\": 1,\n              \"NamePos\": 645,\n              \"NameEnd\": 649\n            },\n            \"Params\": {\n              \"LeftParenPos\": 649,\n              \"RightParenPos\": 650,\n              \"Items\": {\n                \"ListPos\": 650,\n                \"ListEnd\": 650,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 652,\n          \"OverExpr\": {\n            \"Name\": \"w1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 657,\n            \"NameEnd\": 659\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rank_w1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 762,\n          \"NameEnd\": 769\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 775,\n              \"NameEnd\": 778\n            },\n            \"Params\": {\n              \"LeftParenPos\": 778,\n              \"RightParenPos\": 780,\n              \"Items\": {\n                \"ListPos\": 779,\n                \"ListEnd\": 780,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 779,\n                      \"NameEnd\": 780\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 782,\n          \"OverExpr\": {\n            \"Name\": \"w1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 787,\n            \"NameEnd\": 789\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"sum_w1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 892,\n          \"NameEnd\": 898\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 953,\n              \"NameEnd\": 956\n            },\n            \"Params\": {\n              \"LeftParenPos\": 956,\n              \"RightParenPos\": 958,\n              \"Items\": {\n                \"ListPos\": 957,\n                \"ListEnd\": 958,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 957,\n                      \"NameEnd\": 958\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 960,\n          \"OverExpr\": {\n            \"LeftParenPos\": 965,\n            \"RightParenPos\": 983,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": {\n              \"FramePos\": 966,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Number\": {\n                  \"NumPos\": 971,\n                  \"NumEnd\": 973,\n                  \"Literal\": \"10\",\n                  \"Base\": 10\n                },\n                \"EndPos\": 983,\n                \"Direction\": \"PRECEDING\"\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rows_10_preceding\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1070,\n          \"NameEnd\": 1087\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1093,\n              \"NameEnd\": 1096\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1096,\n              \"RightParenPos\": 1098,\n              \"Items\": {\n                \"ListPos\": 1097,\n                \"ListEnd\": 1098,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1097,\n                      \"NameEnd\": 1098\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1100,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1105,\n            \"RightParenPos\": 1154,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": {\n              \"FramePos\": 1106,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"CurrentPos\": 1119,\n                  \"RowEnd\": 1134\n                },\n                \"AndPos\": 1131,\n                \"And\": {\n                  \"UnboundedPos\": 1135,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rows_cur_to_unbounded_following\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1210,\n          \"NameEnd\": 1241\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1247,\n              \"NameEnd\": 1250\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1250,\n              \"RightParenPos\": 1252,\n              \"Items\": {\n                \"ListPos\": 1251,\n                \"ListEnd\": 1252,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1251,\n                      \"NameEnd\": 1252\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1254,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1259,\n            \"RightParenPos\": 1300,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": {\n              \"FramePos\": 1260,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 1273,\n                    \"NumEnd\": 1274,\n                    \"Literal\": \"5\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 1284,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 1285,\n                \"And\": {\n                  \"Number\": {\n                    \"NumPos\": 1289,\n                    \"NumEnd\": 1290,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 1300,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rows_5p_3f\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1364,\n          \"NameEnd\": 1374\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1380,\n              \"NameEnd\": 1383\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1383,\n              \"RightParenPos\": 1385,\n              \"Items\": {\n                \"ListPos\": 1384,\n                \"ListEnd\": 1385,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1384,\n                      \"NameEnd\": 1385\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1387,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1392,\n            \"RightParenPos\": 1435,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": {\n              \"FramePos\": 1393,\n              \"Type\": \"RANGE\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 1407,\n                    \"NumEnd\": 1409,\n                    \"Literal\": \"10\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 1419,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 1420,\n                \"And\": {\n                  \"CurrentPos\": 1424,\n                  \"RowEnd\": 1436\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"range_10p_cur\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1497,\n          \"NameEnd\": 1510\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1516,\n              \"NameEnd\": 1519\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1519,\n              \"RightParenPos\": 1521,\n              \"Items\": {\n                \"ListPos\": 1520,\n                \"ListEnd\": 1521,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1520,\n                      \"NameEnd\": 1521\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1523,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1528,\n            \"RightParenPos\": 1578,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": {\n              \"FramePos\": 1529,\n              \"Type\": \"RANGE\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 1543,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 1563,\n                \"And\": {\n                  \"CurrentPos\": 1567,\n                  \"RowEnd\": 1579\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"range_unbounded_to_cur\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1633,\n          \"NameEnd\": 1655\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"row_number\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1690,\n              \"NameEnd\": 1700\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1700,\n              \"RightParenPos\": 1701,\n              \"Items\": {\n                \"ListPos\": 1701,\n                \"ListEnd\": 1701,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1703,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1708,\n            \"RightParenPos\": 1734,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 1708,\n              \"Expr\": {\n                \"ListPos\": 1722,\n                \"ListEnd\": 1723,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1722,\n                      \"NameEnd\": 1723\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 1724,\n              \"ListEnd\": 1734,\n              \"Items\": [\n                {\n                  \"OrderPos\": 1724,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 1733,\n                    \"NameEnd\": 1734\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"row_num\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1807,\n          \"NameEnd\": 1814\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"rank\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1820,\n              \"NameEnd\": 1824\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1824,\n              \"RightParenPos\": 1825,\n              \"Items\": {\n                \"ListPos\": 1825,\n                \"ListEnd\": 1825,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1827,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1832,\n            \"RightParenPos\": 1858,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 1832,\n              \"Expr\": {\n                \"ListPos\": 1846,\n                \"ListEnd\": 1847,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1846,\n                      \"NameEnd\": 1847\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 1848,\n              \"ListEnd\": 1858,\n              \"Items\": [\n                {\n                  \"OrderPos\": 1848,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 1857,\n                    \"NameEnd\": 1858\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rank_val\",\n          \"QuoteType\": 1,\n          \"NamePos\": 1937,\n          \"NameEnd\": 1945\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"dense_rank\",\n              \"QuoteType\": 1,\n              \"NamePos\": 1951,\n              \"NameEnd\": 1961\n            },\n            \"Params\": {\n              \"LeftParenPos\": 1961,\n              \"RightParenPos\": 1962,\n              \"Items\": {\n                \"ListPos\": 1962,\n                \"ListEnd\": 1962,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 1964,\n          \"OverExpr\": {\n            \"LeftParenPos\": 1969,\n            \"RightParenPos\": 1995,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 1969,\n              \"Expr\": {\n                \"ListPos\": 1983,\n                \"ListEnd\": 1984,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 1983,\n                      \"NameEnd\": 1984\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 1985,\n              \"ListEnd\": 1995,\n              \"Items\": [\n                {\n                  \"OrderPos\": 1985,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 1994,\n                    \"NameEnd\": 1995\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"dense_rank_val\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2068,\n          \"NameEnd\": 2082\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"first_value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2088,\n              \"NameEnd\": 2099\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2099,\n              \"RightParenPos\": 2101,\n              \"Items\": {\n                \"ListPos\": 2100,\n                \"ListEnd\": 2101,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2100,\n                      \"NameEnd\": 2101\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2119,\n          \"OverExpr\": {\n            \"LeftParenPos\": 2124,\n            \"RightParenPos\": 2207,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 2124,\n              \"Expr\": {\n                \"ListPos\": 2138,\n                \"ListEnd\": 2139,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2138,\n                      \"NameEnd\": 2139\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 2140,\n              \"ListEnd\": 2150,\n              \"Items\": [\n                {\n                  \"OrderPos\": 2140,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 2149,\n                    \"NameEnd\": 2150\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 2151,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 2164,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 2184,\n                \"And\": {\n                  \"UnboundedPos\": 2188,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"first_val\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2224,\n          \"NameEnd\": 2233\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"last_value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2239,\n              \"NameEnd\": 2249\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2249,\n              \"RightParenPos\": 2251,\n              \"Items\": {\n                \"ListPos\": 2250,\n                \"ListEnd\": 2251,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2250,\n                      \"NameEnd\": 2251\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2268,\n          \"OverExpr\": {\n            \"LeftParenPos\": 2273,\n            \"RightParenPos\": 2356,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 2273,\n              \"Expr\": {\n                \"ListPos\": 2287,\n                \"ListEnd\": 2288,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2287,\n                      \"NameEnd\": 2288\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 2289,\n              \"ListEnd\": 2299,\n              \"Items\": [\n                {\n                  \"OrderPos\": 2289,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 2298,\n                    \"NameEnd\": 2299\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 2300,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 2313,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 2333,\n                \"And\": {\n                  \"UnboundedPos\": 2337,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"last_val\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2374,\n          \"NameEnd\": 2382\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"lag\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2388,\n              \"NameEnd\": 2391\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2391,\n              \"RightParenPos\": 2396,\n              \"Items\": {\n                \"ListPos\": 2392,\n                \"ListEnd\": 2396,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2392,\n                      \"NameEnd\": 2393\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"NumPos\": 2395,\n                      \"NumEnd\": 2396,\n                      \"Literal\": \"1\",\n                      \"Base\": 10\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2398,\n          \"OverExpr\": {\n            \"LeftParenPos\": 2403,\n            \"RightParenPos\": 2429,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 2403,\n              \"Expr\": {\n                \"ListPos\": 2417,\n                \"ListEnd\": 2418,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2417,\n                      \"NameEnd\": 2418\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 2419,\n              \"ListEnd\": 2429,\n              \"Items\": [\n                {\n                  \"OrderPos\": 2419,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 2428,\n                    \"NameEnd\": 2429\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"prev_x\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2505,\n          \"NameEnd\": 2511\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"lead\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2517,\n              \"NameEnd\": 2521\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2521,\n              \"RightParenPos\": 2526,\n              \"Items\": {\n                \"ListPos\": 2522,\n                \"ListEnd\": 2526,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2522,\n                      \"NameEnd\": 2523\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"NumPos\": 2525,\n                      \"NumEnd\": 2526,\n                      \"Literal\": \"1\",\n                      \"Base\": 10\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2528,\n          \"OverExpr\": {\n            \"LeftParenPos\": 2533,\n            \"RightParenPos\": 2559,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 2533,\n              \"Expr\": {\n                \"ListPos\": 2547,\n                \"ListEnd\": 2548,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2547,\n                      \"NameEnd\": 2548\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 2549,\n              \"ListEnd\": 2559,\n              \"Items\": [\n                {\n                  \"OrderPos\": 2549,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 2558,\n                    \"NameEnd\": 2559\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"next_x\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2634,\n          \"NameEnd\": 2640\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"percent_rank\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2646,\n              \"NameEnd\": 2658\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2658,\n              \"RightParenPos\": 2659,\n              \"Items\": {\n                \"ListPos\": 2659,\n                \"ListEnd\": 2659,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2661,\n          \"OverExpr\": {\n            \"LeftParenPos\": 2666,\n            \"RightParenPos\": 2692,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 2666,\n              \"Expr\": {\n                \"ListPos\": 2680,\n                \"ListEnd\": 2681,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2680,\n                      \"NameEnd\": 2681\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 2682,\n              \"ListEnd\": 2692,\n              \"Items\": [\n                {\n                  \"OrderPos\": 2682,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 2691,\n                    \"NameEnd\": 2692\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"pct_rank\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2763,\n          \"NameEnd\": 2771\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2836,\n              \"NameEnd\": 2839\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2839,\n              \"RightParenPos\": 2841,\n              \"Items\": {\n                \"ListPos\": 2840,\n                \"ListEnd\": 2841,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2840,\n                      \"NameEnd\": 2841\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2843,\n          \"OverExpr\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 2848,\n            \"NameEnd\": 2849\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"sum_over_w\",\n          \"QuoteType\": 1,\n          \"NamePos\": 2953,\n          \"NameEnd\": 2963\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"avg\",\n              \"QuoteType\": 1,\n              \"NamePos\": 2969,\n              \"NameEnd\": 2972\n            },\n            \"Params\": {\n              \"LeftParenPos\": 2972,\n              \"RightParenPos\": 2974,\n              \"Items\": {\n                \"ListPos\": 2973,\n                \"ListEnd\": 2974,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 2973,\n                      \"NameEnd\": 2974\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 2976,\n          \"OverExpr\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 2981,\n            \"NameEnd\": 2982\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"avg_over_w\",\n          \"QuoteType\": 1,\n          \"NamePos\": 3086,\n          \"NameEnd\": 3096\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"row_number\",\n              \"QuoteType\": 1,\n              \"NamePos\": 3102,\n              \"NameEnd\": 3112\n            },\n            \"Params\": {\n              \"LeftParenPos\": 3112,\n              \"RightParenPos\": 3113,\n              \"Items\": {\n                \"ListPos\": 3113,\n                \"ListEnd\": 3113,\n                \"HasDistinct\": false,\n                \"Items\": []\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 3115,\n          \"OverExpr\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 3120,\n            \"NameEnd\": 3121\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rn_over_w\",\n          \"QuoteType\": 1,\n          \"NamePos\": 3219,\n          \"NameEnd\": 3228\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"count\",\n              \"QuoteType\": 1,\n              \"NamePos\": 3286,\n              \"NameEnd\": 3291\n            },\n            \"Params\": {\n              \"LeftParenPos\": 3291,\n              \"RightParenPos\": 3293,\n              \"Items\": {\n                \"ListPos\": 3292,\n                \"ListEnd\": 3292,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"*\",\n                      \"QuoteType\": 0,\n                      \"NamePos\": 3292,\n                      \"NameEnd\": 3292\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 3295,\n          \"OverExpr\": {\n            \"LeftParenPos\": 3300,\n            \"RightParenPos\": 3355,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 3300,\n              \"Expr\": {\n                \"ListPos\": 3314,\n                \"ListEnd\": 3330,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"col1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3314,\n                      \"NameEnd\": 3318\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"col2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3320,\n                      \"NameEnd\": 3324\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"col3\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3326,\n                      \"NameEnd\": 3330\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 3331,\n              \"ListEnd\": 3350,\n              \"Items\": [\n                {\n                  \"OrderPos\": 3331,\n                  \"Expr\": {\n                    \"Name\": \"col4\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3340,\n                    \"NameEnd\": 3344\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                },\n                {\n                  \"OrderPos\": 3331,\n                  \"Expr\": {\n                    \"Name\": \"col5\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3346,\n                    \"NameEnd\": 3350\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"DESC\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"cnt_multi\",\n          \"QuoteType\": 1,\n          \"NamePos\": 3403,\n          \"NameEnd\": 3412\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 3418,\n              \"NameEnd\": 3421\n            },\n            \"Params\": {\n              \"LeftParenPos\": 3421,\n              \"RightParenPos\": 3425,\n              \"Items\": {\n                \"ListPos\": 3422,\n                \"ListEnd\": 3425,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"val\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3422,\n                      \"NameEnd\": 3425\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 3435,\n          \"OverExpr\": {\n            \"LeftParenPos\": 3440,\n            \"RightParenPos\": 3533,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 3440,\n              \"Expr\": {\n                \"ListPos\": 3454,\n                \"ListEnd\": 3464,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"col1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3454,\n                      \"NameEnd\": 3458\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"col2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3460,\n                      \"NameEnd\": 3464\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 3465,\n              \"ListEnd\": 3484,\n              \"Items\": [\n                {\n                  \"OrderPos\": 3465,\n                  \"Expr\": {\n                    \"Name\": \"col4\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3474,\n                    \"NameEnd\": 3478\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                },\n                {\n                  \"OrderPos\": 3465,\n                  \"Expr\": {\n                    \"Name\": \"col5\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3480,\n                    \"NameEnd\": 3484\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 3485,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 3498,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 3518,\n                \"And\": {\n                  \"CurrentPos\": 3522,\n                  \"RowEnd\": 3534\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"total_multi\",\n          \"QuoteType\": 1,\n          \"NamePos\": 3548,\n          \"NameEnd\": 3559\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 3604,\n              \"NameEnd\": 3607\n            },\n            \"Params\": {\n              \"LeftParenPos\": 3607,\n              \"RightParenPos\": 3614,\n              \"Items\": {\n                \"ListPos\": 3608,\n                \"ListEnd\": 3614,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"amount\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3608,\n                      \"NameEnd\": 3614\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 3624,\n          \"OverExpr\": {\n            \"LeftParenPos\": 3629,\n            \"RightParenPos\": 3732,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 3629,\n              \"Expr\": {\n                \"ListPos\": 3643,\n                \"ListEnd\": 3670,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"date_trunc\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 3643,\n                        \"NameEnd\": 3653\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 3653,\n                        \"RightParenPos\": 3670,\n                        \"Items\": {\n                          \"ListPos\": 3655,\n                          \"ListEnd\": 3670,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 3655,\n                                \"LiteralEnd\": 3658,\n                                \"Literal\": \"day\"\n                              },\n                              \"Alias\": null\n                            },\n                            {\n                              \"Expr\": {\n                                \"Name\": \"timestamp\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 3661,\n                                \"NameEnd\": 3670\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 3672,\n              \"ListEnd\": 3690,\n              \"Items\": [\n                {\n                  \"OrderPos\": 3672,\n                  \"Expr\": {\n                    \"Name\": \"timestamp\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3681,\n                    \"NameEnd\": 3690\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 3691,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 3704,\n                    \"NumEnd\": 3706,\n                    \"Literal\": \"10\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 3716,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 3717,\n                \"And\": {\n                  \"CurrentPos\": 3721,\n                  \"RowEnd\": 3733\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"daily_total\",\n          \"QuoteType\": 1,\n          \"NamePos\": 3737,\n          \"NameEnd\": 3748\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"avg\",\n              \"QuoteType\": 1,\n              \"NamePos\": 3754,\n              \"NameEnd\": 3757\n            },\n            \"Params\": {\n              \"LeftParenPos\": 3757,\n              \"RightParenPos\": 3764,\n              \"Items\": {\n                \"ListPos\": 3758,\n                \"ListEnd\": 3764,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"amount\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3758,\n                      \"NameEnd\": 3764\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 3774,\n          \"OverExpr\": {\n            \"LeftParenPos\": 3779,\n            \"RightParenPos\": 3859,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 3780,\n              \"ListEnd\": 3816,\n              \"Items\": [\n                {\n                  \"OrderPos\": 3780,\n                  \"Expr\": {\n                    \"ExtractPos\": 3780,\n                    \"ExtractEnd\": 3816,\n                    \"Parameters\": [\n                      {\n                        \"Interval\": {\n                          \"Name\": \"HOUR\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 3797,\n                          \"NameEnd\": 3801\n                        },\n                        \"FromPos\": 3802,\n                        \"FromExpr\": {\n                          \"Name\": \"timestamp\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 3807,\n                          \"NameEnd\": 3816\n                        }\n                      }\n                    ]\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 3818,\n              \"Type\": \"RANGE\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 3832,\n                    \"NumEnd\": 3833,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 3843,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 3844,\n                \"And\": {\n                  \"Number\": {\n                    \"NumPos\": 3848,\n                    \"NumEnd\": 3849,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 3859,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"hourly_avg\",\n          \"QuoteType\": 1,\n          \"NamePos\": 3887,\n          \"NameEnd\": 3897\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 3898,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 3903,\n          \"TableEnd\": 3904,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 3903,\n              \"NameEnd\": 3904\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 3904,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": {\n      \"WindowPos\": 3905,\n      \"EndPos\": 4194,\n      \"Windows\": [\n        {\n          \"Name\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 3912,\n            \"NameEnd\": 3913\n          },\n          \"AsPos\": 3914,\n          \"Expr\": {\n            \"LeftParenPos\": 3917,\n            \"RightParenPos\": 3928,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 3918,\n              \"ListEnd\": 3928,\n              \"Items\": [\n                {\n                  \"OrderPos\": 3918,\n                  \"Expr\": {\n                    \"Name\": \"y\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3927,\n                    \"NameEnd\": 3928\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        },\n        {\n          \"Name\": {\n            \"Name\": \"w1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 3938,\n            \"NameEnd\": 3940\n          },\n          \"AsPos\": 3941,\n          \"Expr\": {\n            \"LeftParenPos\": 3944,\n            \"RightParenPos\": 4019,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 3944,\n              \"Expr\": {\n                \"ListPos\": 3958,\n                \"ListEnd\": 3959,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 3958,\n                      \"NameEnd\": 3959\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 3960,\n              \"ListEnd\": 3970,\n              \"Items\": [\n                {\n                  \"OrderPos\": 3960,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 3969,\n                    \"NameEnd\": 3970\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 3971,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 3984,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 4004,\n                \"And\": {\n                  \"CurrentPos\": 4008,\n                  \"RowEnd\": 4020\n                }\n              }\n            }\n          }\n        },\n        {\n          \"Name\": {\n            \"Name\": \"w4\",\n            \"QuoteType\": 1,\n            \"NamePos\": 4029,\n            \"NameEnd\": 4031\n          },\n          \"AsPos\": 4032,\n          \"Expr\": {\n            \"LeftParenPos\": 4035,\n            \"RightParenPos\": 4102,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 4035,\n              \"Expr\": {\n                \"ListPos\": 4049,\n                \"ListEnd\": 4050,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 4049,\n                      \"NameEnd\": 4050\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 4051,\n              \"ListEnd\": 4061,\n              \"Items\": [\n                {\n                  \"OrderPos\": 4051,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 4060,\n                    \"NameEnd\": 4061\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 4062,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 4075,\n                    \"NumEnd\": 4076,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 4086,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 4087,\n                \"And\": {\n                  \"CurrentPos\": 4091,\n                  \"RowEnd\": 4103\n                }\n              }\n            }\n          }\n        },\n        {\n          \"Name\": {\n            \"Name\": \"w5\",\n            \"QuoteType\": 1,\n            \"NamePos\": 4112,\n            \"NameEnd\": 4114\n          },\n          \"AsPos\": 4115,\n          \"Expr\": {\n            \"LeftParenPos\": 4118,\n            \"RightParenPos\": 4194,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 4118,\n              \"Expr\": {\n                \"ListPos\": 4132,\n                \"ListEnd\": 4133,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"z\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 4132,\n                      \"NameEnd\": 4133\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 4134,\n              \"ListEnd\": 4144,\n              \"Items\": [\n                {\n                  \"OrderPos\": 4134,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 4143,\n                    \"NameEnd\": 4144\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 4145,\n              \"Type\": \"RANGE\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 4159,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 4179,\n                \"And\": {\n                  \"CurrentPos\": 4183,\n                  \"RowEnd\": 4195\n                }\n              }\n            }\n          }\n        }\n      ]\n    },\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_window_cte.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 746,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 249,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 9,\n          \"Expr\": {\n            \"Name\": \"monthly\",\n            \"QuoteType\": 1,\n            \"NamePos\": 9,\n            \"NameEnd\": 16\n          },\n          \"Alias\": {\n            \"SelectPos\": 30,\n            \"StatementEnd\": 236,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"Name\": {\n                    \"Name\": \"toStartOfMonth\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 37,\n                    \"NameEnd\": 51\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 51,\n                    \"RightParenPos\": 56,\n                    \"Items\": {\n                      \"ListPos\": 52,\n                      \"ListEnd\": 56,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Name\": \"date\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 52,\n                            \"NameEnd\": 56\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"month\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 61,\n                  \"NameEnd\": 66\n                }\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"department\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 83,\n                  \"NameEnd\": 93\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": {\n                    \"Name\": \"avg\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 110,\n                    \"NameEnd\": 113\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 113,\n                    \"RightParenPos\": 120,\n                    \"Items\": {\n                      \"ListPos\": 114,\n                      \"ListEnd\": 120,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Name\": \"salary\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 114,\n                            \"NameEnd\": 120\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"avg_salary\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 134,\n                  \"NameEnd\": 144\n                }\n              }\n            ],\n            \"From\": {\n              \"FromPos\": 153,\n              \"Expr\": {\n                \"Table\": {\n                  \"TablePos\": 158,\n                  \"TableEnd\": 170,\n                  \"Alias\": null,\n                  \"Expr\": {\n                    \"Database\": null,\n                    \"Table\": {\n                      \"Name\": \"salary_table\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 158,\n                      \"NameEnd\": 170\n                    }\n                  },\n                  \"HasFinal\": false\n                },\n                \"StatementEnd\": 170,\n                \"SampleRatio\": null,\n                \"HasFinal\": false\n              }\n            },\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": {\n              \"WherePos\": 179,\n              \"Expr\": {\n                \"LeftExpr\": {\n                  \"Name\": \"year\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 185,\n                  \"NameEnd\": 189\n                },\n                \"Operation\": \"=\",\n                \"RightExpr\": {\n                  \"NumPos\": 192,\n                  \"NumEnd\": 196,\n                  \"Literal\": \"2023\",\n                  \"Base\": 10\n                },\n                \"HasGlobal\": false,\n                \"HasNot\": false\n              }\n            },\n            \"GroupBy\": {\n              \"GroupByPos\": 205,\n              \"GroupByEnd\": 236,\n              \"AggregateType\": \"\",\n              \"Expr\": {\n                \"ListPos\": 214,\n                \"ListEnd\": 231,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"month\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 214,\n                      \"NameEnd\": 219\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"department\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 221,\n                      \"NameEnd\": 231\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"WithCube\": false,\n              \"WithRollup\": false,\n              \"WithTotals\": false\n            },\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        },\n        {\n          \"CTEPos\": 243,\n          \"Expr\": {\n            \"Name\": \"ranked\",\n            \"QuoteType\": 1,\n            \"NamePos\": 243,\n            \"NameEnd\": 249\n          },\n          \"Alias\": {\n            \"SelectPos\": 263,\n            \"StatementEnd\": 448,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"month\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 270,\n                  \"NameEnd\": 275\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"department\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 292,\n                  \"NameEnd\": 302\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Name\": \"avg_salary\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 319,\n                  \"NameEnd\": 329\n                },\n                \"Modifiers\": [],\n                \"Alias\": null\n              },\n              {\n                \"Expr\": {\n                  \"Function\": {\n                    \"Name\": {\n                      \"Name\": \"row_number\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 346,\n                      \"NameEnd\": 356\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 356,\n                      \"RightParenPos\": 357,\n                      \"Items\": {\n                        \"ListPos\": 357,\n                        \"ListEnd\": 357,\n                        \"HasDistinct\": false,\n                        \"Items\": []\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"OverPos\": 359,\n                  \"OverExpr\": {\n                    \"LeftParenPos\": 364,\n                    \"RightParenPos\": 413,\n                    \"WindowName\": null,\n                    \"PartitionBy\": {\n                      \"PartitionPos\": 364,\n                      \"Expr\": {\n                        \"ListPos\": 378,\n                        \"ListEnd\": 388,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": \"department\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 378,\n                              \"NameEnd\": 388\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      }\n                    },\n                    \"OrderBy\": {\n                      \"OrderPos\": 389,\n                      \"ListEnd\": 408,\n                      \"Items\": [\n                        {\n                          \"OrderPos\": 389,\n                          \"Expr\": {\n                            \"Name\": \"avg_salary\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 398,\n                            \"NameEnd\": 408\n                          },\n                          \"Alias\": null,\n                          \"Direction\": \"DESC\",\n                          \"Fill\": null\n                        }\n                      ],\n                      \"Interpolate\": null\n                    },\n                    \"Frame\": null\n                  }\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"dept_rank\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 418,\n                  \"NameEnd\": 427\n                }\n              }\n            ],\n            \"From\": {\n              \"FromPos\": 436,\n              \"Expr\": {\n                \"Table\": {\n                  \"TablePos\": 441,\n                  \"TableEnd\": 448,\n                  \"Alias\": null,\n                  \"Expr\": {\n                    \"Database\": null,\n                    \"Table\": {\n                      \"Name\": \"monthly\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 441,\n                      \"NameEnd\": 448\n                    }\n                  },\n                  \"HasFinal\": false\n                },\n                \"StatementEnd\": 448,\n                \"SampleRatio\": null,\n                \"HasFinal\": false\n              }\n            },\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"month\",\n          \"QuoteType\": 1,\n          \"NamePos\": 462,\n          \"NameEnd\": 467\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"department\",\n          \"QuoteType\": 1,\n          \"NamePos\": 476,\n          \"NameEnd\": 486\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"avg_salary\",\n          \"QuoteType\": 1,\n          \"NamePos\": 495,\n          \"NameEnd\": 505\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"lag\",\n              \"QuoteType\": 1,\n              \"NamePos\": 514,\n              \"NameEnd\": 517\n            },\n            \"Params\": {\n              \"LeftParenPos\": 517,\n              \"RightParenPos\": 534,\n              \"Items\": {\n                \"ListPos\": 518,\n                \"ListEnd\": 534,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"avg_salary\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 518,\n                      \"NameEnd\": 528\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"NumPos\": 530,\n                      \"NumEnd\": 531,\n                      \"Literal\": \"1\",\n                      \"Base\": 10\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"NumPos\": 533,\n                      \"NumEnd\": 534,\n                      \"Literal\": \"0\",\n                      \"Base\": 10\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 536,\n          \"OverExpr\": {\n            \"LeftParenPos\": 541,\n            \"RightParenPos\": 667,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 541,\n              \"Expr\": {\n                \"ListPos\": 567,\n                \"ListEnd\": 577,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"department\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 567,\n                      \"NameEnd\": 577\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 589,\n              \"ListEnd\": 603,\n              \"Items\": [\n                {\n                  \"OrderPos\": 589,\n                  \"Expr\": {\n                    \"Name\": \"month\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 598,\n                    \"NameEnd\": 603\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 615,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 628,\n                    \"NumEnd\": 629,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 639,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 640,\n                \"And\": {\n                  \"CurrentPos\": 644,\n                  \"RowEnd\": 668\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"prev_month_avg\",\n          \"QuoteType\": 1,\n          \"NamePos\": 672,\n          \"NameEnd\": 686\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 687,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 692,\n          \"TableEnd\": 698,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"ranked\",\n              \"QuoteType\": 1,\n              \"NamePos\": 692,\n              \"NameEnd\": 698\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 698,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 699,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Name\": \"dept_rank\",\n          \"QuoteType\": 1,\n          \"NamePos\": 705,\n          \"NameEnd\": 714\n        },\n        \"Operation\": \"\\u003c=\",\n        \"RightExpr\": {\n          \"NumPos\": 718,\n          \"NumEnd\": 719,\n          \"Literal\": \"5\",\n          \"Base\": 10\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 720,\n      \"ListEnd\": 746,\n      \"Items\": [\n        {\n          \"OrderPos\": 720,\n          \"Expr\": {\n            \"Name\": \"month\",\n            \"QuoteType\": 1,\n            \"NamePos\": 729,\n            \"NameEnd\": 734\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": null\n        },\n        {\n          \"OrderPos\": 720,\n          \"Expr\": {\n            \"Name\": \"department\",\n            \"QuoteType\": 1,\n            \"NamePos\": 736,\n            \"NameEnd\": 746\n          },\n          \"Alias\": null,\n          \"Direction\": \"\",\n          \"Fill\": null\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_window_keyword_name_in_parens.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 98,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 7,\n              \"NameEnd\": 10\n            },\n            \"Params\": {\n              \"LeftParenPos\": 10,\n              \"RightParenPos\": 12,\n              \"Items\": {\n                \"ListPos\": 11,\n                \"ListEnd\": 12,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 11,\n                      \"NameEnd\": 12\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 14,\n          \"OverExpr\": {\n            \"LeftParenPos\": 19,\n            \"RightParenPos\": 25,\n            \"WindowName\": {\n              \"Name\": \"order\",\n              \"QuoteType\": 1,\n              \"NamePos\": 20,\n              \"NameEnd\": 25\n            },\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"sum_over_order\",\n          \"QuoteType\": 1,\n          \"NamePos\": 30,\n          \"NameEnd\": 44\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 45,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 50,\n          \"TableEnd\": 51,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 50,\n              \"NameEnd\": 51\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 51,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": {\n      \"WindowPos\": 52,\n      \"EndPos\": 98,\n      \"Windows\": [\n        {\n          \"Name\": {\n            \"Name\": \"order\",\n            \"QuoteType\": 1,\n            \"NamePos\": 59,\n            \"NameEnd\": 64\n          },\n          \"AsPos\": 65,\n          \"Expr\": {\n            \"LeftParenPos\": 68,\n            \"RightParenPos\": 98,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 68,\n              \"Expr\": {\n                \"ListPos\": 82,\n                \"ListEnd\": 86,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"team\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 82,\n                      \"NameEnd\": 86\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 87,\n              \"ListEnd\": 98,\n              \"Items\": [\n                {\n                  \"OrderPos\": 87,\n                  \"Expr\": {\n                    \"Name\": \"ts\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 96,\n                    \"NameEnd\": 98\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        }\n      ]\n    },\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_window_named_in_parens.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 82,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 7,\n              \"NameEnd\": 10\n            },\n            \"Params\": {\n              \"LeftParenPos\": 10,\n              \"RightParenPos\": 12,\n              \"Items\": {\n                \"ListPos\": 11,\n                \"ListEnd\": 12,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 11,\n                      \"NameEnd\": 12\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 14,\n          \"OverExpr\": {\n            \"LeftParenPos\": 19,\n            \"RightParenPos\": 21,\n            \"WindowName\": {\n              \"Name\": \"w\",\n              \"QuoteType\": 1,\n              \"NamePos\": 20,\n              \"NameEnd\": 21\n            },\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"sum_over_w\",\n          \"QuoteType\": 1,\n          \"NamePos\": 26,\n          \"NameEnd\": 36\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 37,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 42,\n          \"TableEnd\": 43,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 42,\n              \"NameEnd\": 43\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 43,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": {\n      \"WindowPos\": 44,\n      \"EndPos\": 82,\n      \"Windows\": [\n        {\n          \"Name\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 51,\n            \"NameEnd\": 52\n          },\n          \"AsPos\": 53,\n          \"Expr\": {\n            \"LeftParenPos\": 56,\n            \"RightParenPos\": 82,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 56,\n              \"Expr\": {\n                \"ListPos\": 70,\n                \"ListEnd\": 71,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"y\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 70,\n                      \"NameEnd\": 71\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 72,\n              \"ListEnd\": 82,\n              \"Items\": [\n                {\n                  \"OrderPos\": 72,\n                  \"Expr\": {\n                    \"Name\": \"x\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 81,\n                    \"NameEnd\": 82\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": null\n          }\n        }\n      ]\n    },\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_window_named_reference_extensions.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 303,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 7,\n              \"NameEnd\": 10\n            },\n            \"Params\": {\n              \"LeftParenPos\": 10,\n              \"RightParenPos\": 12,\n              \"Items\": {\n                \"ListPos\": 11,\n                \"ListEnd\": 12,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 11,\n                      \"NameEnd\": 12\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 14,\n          \"OverExpr\": {\n            \"LeftParenPos\": 19,\n            \"RightParenPos\": 75,\n            \"WindowName\": {\n              \"Name\": \"w1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 20,\n              \"NameEnd\": 22\n            },\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 23,\n              \"ListEnd\": 34,\n              \"Items\": [\n                {\n                  \"OrderPos\": 23,\n                  \"Expr\": {\n                    \"Name\": \"ts\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 32,\n                    \"NameEnd\": 34\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 35,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Number\": {\n                    \"NumPos\": 48,\n                    \"NumEnd\": 49,\n                    \"Literal\": \"1\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 59,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 60,\n                \"And\": {\n                  \"CurrentPos\": 64,\n                  \"RowEnd\": 76\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rolling_sum\",\n          \"QuoteType\": 1,\n          \"NamePos\": 80,\n          \"NameEnd\": 91\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"avg\",\n              \"QuoteType\": 1,\n              \"NamePos\": 100,\n              \"NameEnd\": 103\n            },\n            \"Params\": {\n              \"LeftParenPos\": 103,\n              \"RightParenPos\": 105,\n              \"Items\": {\n                \"ListPos\": 104,\n                \"ListEnd\": 105,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 104,\n                      \"NameEnd\": 105\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 107,\n          \"OverExpr\": {\n            \"LeftParenPos\": 112,\n            \"RightParenPos\": 115,\n            \"WindowName\": {\n              \"Name\": \"w2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 113,\n              \"NameEnd\": 115\n            },\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"avg_over_w2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 173,\n          \"NameEnd\": 184\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 185,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 190,\n          \"TableEnd\": 191,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 190,\n              \"NameEnd\": 191\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 191,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": {\n      \"WindowPos\": 192,\n      \"EndPos\": 303,\n      \"Windows\": [\n        {\n          \"Name\": {\n            \"Name\": \"w1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 199,\n            \"NameEnd\": 201\n          },\n          \"AsPos\": 202,\n          \"Expr\": {\n            \"LeftParenPos\": 205,\n            \"RightParenPos\": 223,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 205,\n              \"Expr\": {\n                \"ListPos\": 219,\n                \"ListEnd\": 223,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"team\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 219,\n                      \"NameEnd\": 223\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": null,\n            \"Frame\": null\n          }\n        },\n        {\n          \"Name\": {\n            \"Name\": \"w2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 233,\n            \"NameEnd\": 235\n          },\n          \"AsPos\": 236,\n          \"Expr\": {\n            \"LeftParenPos\": 239,\n            \"RightParenPos\": 303,\n            \"WindowName\": {\n              \"Name\": \"w1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 240,\n              \"NameEnd\": 242\n            },\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 243,\n              \"ListEnd\": 254,\n              \"Items\": [\n                {\n                  \"OrderPos\": 243,\n                  \"Expr\": {\n                    \"Name\": \"ts\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 252,\n                    \"NameEnd\": 254\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 255,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 268,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 288,\n                \"And\": {\n                  \"CurrentPos\": 292,\n                  \"RowEnd\": 304\n                }\n              }\n            }\n          }\n        }\n      ]\n    },\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_window_params.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 100,\n    \"StatementEnd\": 663,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 107,\n              \"NameEnd\": 110\n            },\n            \"Params\": {\n              \"LeftParenPos\": 110,\n              \"RightParenPos\": 112,\n              \"Items\": {\n                \"ListPos\": 111,\n                \"ListEnd\": 112,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 111,\n                      \"NameEnd\": 112\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 114,\n          \"OverExpr\": {\n            \"LeftParenPos\": 119,\n            \"RightParenPos\": 184,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 120,\n              \"ListEnd\": 130,\n              \"Items\": [\n                {\n                  \"OrderPos\": 120,\n                  \"Expr\": {\n                    \"Name\": \"y\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 129,\n                    \"NameEnd\": 130\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 131,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Param\": {\n                    \"LBracePos\": 144,\n                    \"RBracePos\": 157,\n                    \"Name\": {\n                      \"Name\": \"start\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 145,\n                      \"NameEnd\": 150\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"UInt32\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 151,\n                        \"NameEnd\": 157\n                      }\n                    }\n                  },\n                  \"EndPos\": 168,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 169,\n                \"And\": {\n                  \"CurrentPos\": 173,\n                  \"RowEnd\": 185\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"total1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 215,\n          \"NameEnd\": 221\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"avg\",\n              \"QuoteType\": 1,\n              \"NamePos\": 230,\n              \"NameEnd\": 233\n            },\n            \"Params\": {\n              \"LeftParenPos\": 233,\n              \"RightParenPos\": 235,\n              \"Items\": {\n                \"ListPos\": 234,\n                \"ListEnd\": 235,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 234,\n                      \"NameEnd\": 235\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 237,\n          \"OverExpr\": {\n            \"LeftParenPos\": 242,\n            \"RightParenPos\": 305,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 243,\n              \"ListEnd\": 253,\n              \"Items\": [\n                {\n                  \"OrderPos\": 243,\n                  \"Expr\": {\n                    \"Name\": \"y\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 252,\n                    \"NameEnd\": 253\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 254,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"CurrentPos\": 267,\n                  \"RowEnd\": 282\n                },\n                \"AndPos\": 279,\n                \"And\": {\n                  \"Param\": {\n                    \"LBracePos\": 283,\n                    \"RBracePos\": 294,\n                    \"Name\": {\n                      \"Name\": \"end\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 284,\n                      \"NameEnd\": 287\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"UInt32\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 288,\n                        \"NameEnd\": 294\n                      }\n                    }\n                  },\n                  \"EndPos\": 305,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"avg1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 338,\n          \"NameEnd\": 342\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"count\",\n              \"QuoteType\": 1,\n              \"NamePos\": 351,\n              \"NameEnd\": 356\n            },\n            \"Params\": {\n              \"LeftParenPos\": 356,\n              \"RightParenPos\": 358,\n              \"Items\": {\n                \"ListPos\": 357,\n                \"ListEnd\": 357,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"*\",\n                      \"QuoteType\": 0,\n                      \"NamePos\": 357,\n                      \"NameEnd\": 357\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 360,\n          \"OverExpr\": {\n            \"LeftParenPos\": 365,\n            \"RightParenPos\": 454,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": {\n              \"OrderPos\": 366,\n              \"ListEnd\": 376,\n              \"Items\": [\n                {\n                  \"OrderPos\": 366,\n                  \"Expr\": {\n                    \"Name\": \"y\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 375,\n                    \"NameEnd\": 376\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 377,\n              \"Type\": \"RANGE\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"Param\": {\n                    \"LBracePos\": 391,\n                    \"RBracePos\": 410,\n                    \"Name\": {\n                      \"Name\": \"range_start\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 392,\n                      \"NameEnd\": 403\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"UInt32\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 404,\n                        \"NameEnd\": 410\n                      }\n                    }\n                  },\n                  \"EndPos\": 421,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 422,\n                \"And\": {\n                  \"Param\": {\n                    \"LBracePos\": 426,\n                    \"RBracePos\": 443,\n                    \"Name\": {\n                      \"Name\": \"range_end\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 427,\n                      \"NameEnd\": 436\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"UInt32\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 437,\n                        \"NameEnd\": 443\n                      }\n                    }\n                  },\n                  \"EndPos\": 454,\n                  \"Direction\": \"FOLLOWING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"cnt1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 459,\n          \"NameEnd\": 463\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"sum\",\n              \"QuoteType\": 1,\n              \"NamePos\": 472,\n              \"NameEnd\": 475\n            },\n            \"Params\": {\n              \"LeftParenPos\": 475,\n              \"RightParenPos\": 477,\n              \"Items\": {\n                \"ListPos\": 476,\n                \"ListEnd\": 477,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"x\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 476,\n                      \"NameEnd\": 477\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 479,\n          \"OverExpr\": {\n            \"LeftParenPos\": 484,\n            \"RightParenPos\": 521,\n            \"WindowName\": null,\n            \"PartitionBy\": null,\n            \"OrderBy\": null,\n            \"Frame\": {\n              \"FramePos\": 485,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Param\": {\n                  \"LBracePos\": 490,\n                  \"RBracePos\": 510,\n                  \"Name\": {\n                    \"Name\": \"window_size\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 491,\n                    \"NameEnd\": 502\n                  },\n                  \"Type\": {\n                    \"Name\": {\n                      \"Name\": \"UInt32\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 504,\n                      \"NameEnd\": 510\n                    }\n                  }\n                },\n                \"EndPos\": 521,\n                \"Direction\": \"PRECEDING\"\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"rows_shorthand\",\n          \"QuoteType\": 1,\n          \"NamePos\": 580,\n          \"NameEnd\": 594\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 595,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 600,\n          \"TableEnd\": 601,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 600,\n              \"NameEnd\": 601\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 601,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 602,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LeftExpr\": {\n            \"Name\": \"category\",\n            \"QuoteType\": 1,\n            \"NamePos\": 608,\n            \"NameEnd\": 616\n          },\n          \"Operation\": \"=\",\n          \"RightExpr\": {\n            \"LBracePos\": 619,\n            \"RBracePos\": 636,\n            \"Name\": {\n              \"Name\": \"category\",\n              \"QuoteType\": 1,\n              \"NamePos\": 620,\n              \"NameEnd\": 628\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 630,\n                \"NameEnd\": 636\n              }\n            }\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"Operation\": \"AND\",\n        \"RightExpr\": {\n          \"LeftExpr\": {\n            \"Name\": \"type\",\n            \"QuoteType\": 1,\n            \"NamePos\": 644,\n            \"NameEnd\": 648\n          },\n          \"Operation\": \"=\",\n          \"RightExpr\": {\n            \"LBracePos\": 651,\n            \"RBracePos\": 663,\n            \"Name\": {\n              \"Name\": \"type\",\n              \"QuoteType\": 1,\n              \"NamePos\": 652,\n              \"NameEnd\": 656\n            },\n            \"Type\": {\n              \"Name\": {\n                \"Name\": \"String\",\n                \"QuoteType\": 1,\n                \"NamePos\": 657,\n                \"NameEnd\": 663\n              }\n            }\n          },\n          \"HasGlobal\": false,\n          \"HasNot\": false\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_distinct.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 51,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"count\",\n            \"QuoteType\": 1,\n            \"NamePos\": 7,\n            \"NameEnd\": 12\n          },\n          \"Params\": {\n            \"LeftParenPos\": 12,\n            \"RightParenPos\": 32,\n            \"Items\": {\n              \"ListPos\": 13,\n              \"ListEnd\": 31,\n              \"HasDistinct\": true,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftParenPos\": 21,\n                    \"RightParenPos\": 31,\n                    \"Items\": {\n                      \"ListPos\": 22,\n                      \"ListEnd\": 31,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Name\": \"RECORD_ID\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 22,\n                            \"NameEnd\": 31\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 34,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 39,\n          \"TableEnd\": 51,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"RECORD_TABLE\",\n              \"QuoteType\": 1,\n              \"NamePos\": 39,\n              \"NameEnd\": 51\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 51,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_distinct_keyword.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 38,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": true,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"record_id\",\n          \"QuoteType\": 1,\n          \"NamePos\": 16,\n          \"NameEnd\": 25\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 26,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 31,\n          \"TableEnd\": 38,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"records\",\n              \"QuoteType\": 1,\n              \"NamePos\": 31,\n              \"NameEnd\": 38\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 38,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_distinct_on_dotted_columns.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 73,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": true,\n    \"DistinctOn\": {\n      \"Idents\": [\n        {\n          \"Ident\": {\n            \"Name\": \"t\",\n            \"QuoteType\": 1,\n            \"NamePos\": 20,\n            \"NameEnd\": 21\n          },\n          \"DotIdent\": {\n            \"Name\": \"id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 22,\n            \"NameEnd\": 24\n          }\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"t\",\n            \"QuoteType\": 1,\n            \"NamePos\": 26,\n            \"NameEnd\": 27\n          },\n          \"DotIdent\": {\n            \"Name\": \"name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 28,\n            \"NameEnd\": 32\n          }\n        }\n      ],\n      \"DistinctOnPos\": 16,\n      \"DistinctOnEnd\": 34\n    },\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 34,\n              \"NameEnd\": 35\n            },\n            {\n              \"Name\": \"id\",\n              \"QuoteType\": 1,\n              \"NamePos\": 36,\n              \"NameEnd\": 38\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 40,\n              \"NameEnd\": 41\n            },\n            {\n              \"Name\": \"name\",\n              \"QuoteType\": 1,\n              \"NamePos\": 42,\n              \"NameEnd\": 46\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 48,\n              \"NameEnd\": 49\n            },\n            {\n              \"Name\": \"value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 50,\n              \"NameEnd\": 55\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 56,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 61,\n          \"TableEnd\": 73,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"test_table\",\n                \"QuoteType\": 1,\n                \"NamePos\": 61,\n                \"NameEnd\": 71\n              }\n            },\n            \"AliasPos\": 72,\n            \"Alias\": {\n              \"Name\": \"t\",\n              \"QuoteType\": 1,\n              \"NamePos\": 72,\n              \"NameEnd\": 73\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 73,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_distinct_on_keyword.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 55,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": true,\n    \"DistinctOn\": {\n      \"Idents\": [\n        {\n          \"Ident\": {\n            \"Name\": \"album\",\n            \"QuoteType\": 1,\n            \"NamePos\": 19,\n            \"NameEnd\": 24\n          },\n          \"DotIdent\": null\n        },\n        {\n          \"Ident\": {\n            \"Name\": \"artist\",\n            \"QuoteType\": 1,\n            \"NamePos\": 25,\n            \"NameEnd\": 31\n          },\n          \"DotIdent\": null\n        }\n      ],\n      \"DistinctOnPos\": 16,\n      \"DistinctOnEnd\": 33\n    },\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"record_id\",\n          \"QuoteType\": 1,\n          \"NamePos\": 33,\n          \"NameEnd\": 42\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 43,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 48,\n          \"TableEnd\": 55,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"records\",\n              \"QuoteType\": 1,\n              \"NamePos\": 48,\n              \"NameEnd\": 55\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 55,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_group_by.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 171,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"datacenter\",\n          \"QuoteType\": 1,\n          \"NamePos\": 11,\n          \"NameEnd\": 21\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"distro\",\n          \"QuoteType\": 1,\n          \"NamePos\": 27,\n          \"NameEnd\": 33\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"SUM\",\n            \"QuoteType\": 1,\n            \"NamePos\": 39,\n            \"NameEnd\": 42\n          },\n          \"Params\": {\n            \"LeftParenPos\": 43,\n            \"RightParenPos\": 52,\n            \"Items\": {\n              \"ListPos\": 44,\n              \"ListEnd\": 52,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"quantity\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 44,\n                    \"NameEnd\": 52\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"qty\",\n          \"QuoteType\": 1,\n          \"NamePos\": 57,\n          \"NameEnd\": 60\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 61,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 70,\n          \"TableEnd\": 77,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"servers\",\n              \"QuoteType\": 1,\n              \"NamePos\": 70,\n              \"NameEnd\": 77\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 77,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": {\n      \"GroupByPos\": 78,\n      \"GroupByEnd\": 171,\n      \"AggregateType\": \"GROUPING SETS\",\n      \"Expr\": {\n        \"LeftParenPos\": 104,\n        \"RightParenPos\": 170,\n        \"Items\": {\n          \"ListPos\": 110,\n          \"ListEnd\": 168,\n          \"HasDistinct\": false,\n          \"Items\": [\n            {\n              \"Expr\": {\n                \"LeftParenPos\": 110,\n                \"RightParenPos\": 128,\n                \"Items\": {\n                  \"ListPos\": 111,\n                  \"ListEnd\": 128,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"datacenter\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 111,\n                        \"NameEnd\": 121\n                      },\n                      \"Alias\": null\n                    },\n                    {\n                      \"Expr\": {\n                        \"Name\": \"distro\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 122,\n                        \"NameEnd\": 128\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LeftParenPos\": 135,\n                \"RightParenPos\": 146,\n                \"Items\": {\n                  \"ListPos\": 136,\n                  \"ListEnd\": 146,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"datacenter\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 136,\n                        \"NameEnd\": 146\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LeftParenPos\": 153,\n                \"RightParenPos\": 160,\n                \"Items\": {\n                  \"ListPos\": 154,\n                  \"ListEnd\": 160,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"distro\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 154,\n                        \"NameEnd\": 160\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                },\n                \"ColumnArgList\": null\n              },\n              \"Alias\": null\n            },\n            {\n              \"Expr\": {\n                \"LeftParenPos\": 167,\n                \"RightParenPos\": 168,\n                \"Items\": {\n                  \"ListPos\": 168,\n                  \"ListEnd\": 168,\n                  \"HasDistinct\": false,\n                  \"Items\": []\n                },\n                \"ColumnArgList\": null\n              },\n              \"Alias\": null\n            }\n          ]\n        },\n        \"ColumnArgList\": null\n      },\n      \"WithCube\": false,\n      \"WithRollup\": false,\n      \"WithTotals\": false\n    },\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 174,\n    \"StatementEnd\": 264,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"datacenter\",\n          \"QuoteType\": 1,\n          \"NamePos\": 185,\n          \"NameEnd\": 195\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"distro\",\n          \"QuoteType\": 1,\n          \"NamePos\": 201,\n          \"NameEnd\": 207\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"SUM\",\n            \"QuoteType\": 1,\n            \"NamePos\": 213,\n            \"NameEnd\": 216\n          },\n          \"Params\": {\n            \"LeftParenPos\": 217,\n            \"RightParenPos\": 226,\n            \"Items\": {\n              \"ListPos\": 218,\n              \"ListEnd\": 226,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"quantity\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 218,\n                    \"NameEnd\": 226\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"qty\",\n          \"QuoteType\": 1,\n          \"NamePos\": 231,\n          \"NameEnd\": 234\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 235,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 244,\n          \"TableEnd\": 251,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"servers\",\n              \"QuoteType\": 1,\n              \"NamePos\": 244,\n              \"NameEnd\": 251\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 251,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": {\n      \"GroupByPos\": 252,\n      \"GroupByEnd\": 264,\n      \"AggregateType\": \"ALL\",\n      \"Expr\": null,\n      \"WithCube\": false,\n      \"WithRollup\": false,\n      \"WithTotals\": false\n    },\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_join_only.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 36,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 7,\n          \"NameEnd\": 7\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 9,\n      \"Expr\": {\n        \"JoinPos\": 15,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 15,\n            \"TableEnd\": 17,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"t1\",\n                \"QuoteType\": 2,\n                \"NamePos\": 15,\n                \"NameEnd\": 17\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 17,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 19,\n          \"Left\": {\n            \"Table\": {\n              \"TablePos\": 25,\n              \"TableEnd\": 27,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"t2\",\n                  \"QuoteType\": 2,\n                  \"NamePos\": 25,\n                  \"NameEnd\": 27\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 27,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Right\": null,\n          \"Modifiers\": [\n            \"JOIN\"\n          ],\n          \"Constraints\": {\n            \"OnPos\": 29,\n            \"On\": {\n              \"ListPos\": 32,\n              \"ListEnd\": 36,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"true\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 32,\n                    \"NameEnd\": 36\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_keyword_in_group_by.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 181,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"toStartOfInterval\",\n            \"QuoteType\": 1,\n            \"NamePos\": 11,\n            \"NameEnd\": 28\n          },\n          \"Params\": {\n            \"LeftParenPos\": 28,\n            \"RightParenPos\": 59,\n            \"Items\": {\n              \"ListPos\": 29,\n              \"ListEnd\": 58,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"timestamp\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 29,\n                    \"NameEnd\": 38\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"toIntervalMinute\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 40,\n                      \"NameEnd\": 56\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 56,\n                      \"RightParenPos\": 58,\n                      \"Items\": {\n                        \"ListPos\": 57,\n                        \"ListEnd\": 58,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"NumPos\": 57,\n                              \"NumEnd\": 58,\n                              \"Literal\": \"1\",\n                              \"Base\": 10\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"interval\",\n          \"QuoteType\": 1,\n          \"NamePos\": 64,\n          \"NameEnd\": 72\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"column_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 78,\n          \"NameEnd\": 89\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 90,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 95,\n          \"TableEnd\": 100,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 95,\n              \"NameEnd\": 100\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 100,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 101,\n      \"Expr\": {\n        \"Name\": \"true\",\n        \"QuoteType\": 1,\n        \"NamePos\": 107,\n        \"NameEnd\": 111\n      }\n    },\n    \"GroupBy\": {\n      \"GroupByPos\": 112,\n      \"GroupByEnd\": 145,\n      \"AggregateType\": \"\",\n      \"Expr\": {\n        \"ListPos\": 121,\n        \"ListEnd\": 143,\n        \"HasDistinct\": false,\n        \"Items\": [\n          {\n            \"Expr\": {\n              \"LeftParenPos\": 121,\n              \"RightParenPos\": 143,\n              \"Items\": {\n                \"ListPos\": 122,\n                \"ListEnd\": 143,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"interval\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 122,\n                      \"NameEnd\": 130\n                    },\n                    \"Alias\": null\n                  },\n                  {\n                    \"Expr\": {\n                      \"Name\": \"column_name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 132,\n                      \"NameEnd\": 143\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            },\n            \"Alias\": null\n          }\n        ]\n      },\n      \"WithCube\": false,\n      \"WithRollup\": false,\n      \"WithTotals\": false\n    },\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": {\n      \"OrderPos\": 145,\n      \"ListEnd\": 181,\n      \"Items\": [\n        {\n          \"OrderPos\": 145,\n          \"Expr\": {\n            \"LeftParenPos\": 154,\n            \"RightParenPos\": 181,\n            \"Items\": {\n              \"ListPos\": 155,\n              \"ListEnd\": 181,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"interval\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 155,\n                    \"NameEnd\": 163\n                  },\n                  \"Alias\": {\n                    \"Name\": \"i\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 167,\n                    \"NameEnd\": 168\n                  }\n                },\n                {\n                  \"Expr\": {\n                    \"Name\": \"column_name\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 170,\n                    \"NameEnd\": 181\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          },\n          \"Alias\": null,\n          \"Direction\": \"ASC\",\n          \"Fill\": null\n        }\n      ],\n      \"Interpolate\": null\n    },\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_keyword_placeholder.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 20,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LBracePos\": 7,\n          \"RBracePos\": 20,\n          \"Name\": {\n            \"Name\": \"name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 8,\n            \"NameEnd\": 12\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 14,\n              \"NameEnd\": 20\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 23,\n    \"StatementEnd\": 53,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"toString\",\n            \"QuoteType\": 1,\n            \"NamePos\": 30,\n            \"NameEnd\": 38\n          },\n          \"Params\": {\n            \"LeftParenPos\": 38,\n            \"RightParenPos\": 53,\n            \"Items\": {\n              \"ListPos\": 39,\n              \"ListEnd\": 52,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LBracePos\": 39,\n                    \"RBracePos\": 52,\n                    \"Name\": {\n                      \"Name\": \"name\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 40,\n                      \"NameEnd\": 44\n                    },\n                    \"Type\": {\n                      \"Name\": {\n                        \"Name\": \"String\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 46,\n                        \"NameEnd\": 52\n                      }\n                    }\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_left_join.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 151,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 68,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 9,\n          \"Expr\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 9,\n            \"NameEnd\": 11\n          },\n          \"Alias\": {\n            \"SelectPos\": 37,\n            \"StatementEnd\": 54,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"NumPos\": 44,\n                  \"NumEnd\": 45,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"value\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 49,\n                  \"NameEnd\": 54\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        },\n        {\n          \"CTEPos\": 66,\n          \"Expr\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 66,\n            \"NameEnd\": 68\n          },\n          \"Alias\": {\n            \"SelectPos\": 81,\n            \"StatementEnd\": 98,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"NumPos\": 88,\n                  \"NumEnd\": 89,\n                  \"Literal\": \"2\",\n                  \"Base\": 10\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"value\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 93,\n                  \"NameEnd\": 98\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 112,\n          \"NameEnd\": 112\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 114,\n      \"Expr\": {\n        \"JoinPos\": 119,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 119,\n            \"TableEnd\": 121,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"t1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 119,\n                \"NameEnd\": 121\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 121,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 131,\n          \"Left\": {\n            \"Table\": {\n              \"TablePos\": 141,\n              \"TableEnd\": 143,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"t2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 141,\n                  \"NameEnd\": 143\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 143,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Right\": null,\n          \"Modifiers\": [\n            \"LEFT\",\n            \"JOIN\"\n          ],\n          \"Constraints\": {\n            \"OnPos\": 144,\n            \"On\": {\n              \"ListPos\": 147,\n              \"ListEnd\": 151,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"true\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 147,\n                    \"NameEnd\": 151\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_literal_table_name.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 60,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"table_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 17\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 18,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 24,\n          \"TableEnd\": 51,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": {\n              \"Name\": \"information_schema\",\n              \"QuoteType\": 2,\n              \"NamePos\": 24,\n              \"NameEnd\": 42\n            },\n            \"Table\": {\n              \"Name\": \"tables\",\n              \"QuoteType\": 2,\n              \"NamePos\": 45,\n              \"NameEnd\": 51\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 51,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": {\n      \"LimitPos\": 53,\n      \"Limit\": {\n        \"NumPos\": 59,\n        \"NumEnd\": 60,\n        \"Literal\": \"1\",\n        \"Base\": 10\n      },\n      \"Offset\": null\n    },\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_array_and_inner_join.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 313,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": {\n            \"Name\": \"JSONExtractString\",\n            \"QuoteType\": 1,\n            \"NamePos\": 11,\n            \"NameEnd\": 28\n          },\n          \"Params\": {\n            \"LeftParenPos\": 28,\n            \"RightParenPos\": 46,\n            \"Items\": {\n              \"ListPos\": 29,\n              \"ListEnd\": 45,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Fields\": [\n                      {\n                        \"Name\": \"t3\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 29,\n                        \"NameEnd\": 31\n                      },\n                      {\n                        \"Name\": \"props\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 32,\n                        \"NameEnd\": 37\n                      }\n                    ]\n                  },\n                  \"Alias\": null\n                },\n                {\n                  \"Expr\": {\n                    \"LiteralPos\": 40,\n                    \"LiteralEnd\": 45,\n                    \"Literal\": \"value\"\n                  },\n                  \"Alias\": null\n                }\n              ]\n            },\n            \"ColumnArgList\": null\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 51,\n          \"NameEnd\": 56\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 57,\n      \"Expr\": {\n        \"JoinPos\": 62,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 62,\n            \"TableEnd\": 64,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"t1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 62,\n                \"NameEnd\": 64\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 64,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 69,\n          \"Left\": {\n            \"ListPos\": 80,\n            \"ListEnd\": 123,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": {\n                    \"Name\": \"JSONExtractArrayRaw\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 80,\n                    \"NameEnd\": 99\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 99,\n                    \"RightParenPos\": 116,\n                    \"Items\": {\n                      \"ListPos\": 100,\n                      \"ListEnd\": 115,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Fields\": [\n                              {\n                                \"Name\": \"t1\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 100,\n                                \"NameEnd\": 102\n                              },\n                              {\n                                \"Name\": \"props\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 103,\n                                \"NameEnd\": 108\n                              }\n                            ]\n                          },\n                          \"Alias\": null\n                        },\n                        {\n                          \"Expr\": {\n                            \"LiteralPos\": 111,\n                            \"LiteralEnd\": 115,\n                            \"Literal\": \"arr1\"\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Alias\": {\n                  \"Name\": \"a1\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 121,\n                  \"NameEnd\": 123\n                }\n              }\n            ]\n          },\n          \"Right\": {\n            \"JoinPos\": 128,\n            \"Left\": {\n              \"Table\": {\n                \"TablePos\": 139,\n                \"TableEnd\": 141,\n                \"Alias\": null,\n                \"Expr\": {\n                  \"Database\": null,\n                  \"Table\": {\n                    \"Name\": \"t2\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 139,\n                    \"NameEnd\": 141\n                  }\n                },\n                \"HasFinal\": false\n              },\n              \"StatementEnd\": 141,\n              \"SampleRatio\": null,\n              \"HasFinal\": false\n            },\n            \"Right\": {\n              \"JoinPos\": 185,\n              \"Left\": {\n                \"ListPos\": 196,\n                \"ListEnd\": 239,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": {\n                        \"Name\": \"JSONExtractArrayRaw\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 196,\n                        \"NameEnd\": 215\n                      },\n                      \"Params\": {\n                        \"LeftParenPos\": 215,\n                        \"RightParenPos\": 232,\n                        \"Items\": {\n                          \"ListPos\": 216,\n                          \"ListEnd\": 231,\n                          \"HasDistinct\": false,\n                          \"Items\": [\n                            {\n                              \"Expr\": {\n                                \"Fields\": [\n                                  {\n                                    \"Name\": \"t2\",\n                                    \"QuoteType\": 1,\n                                    \"NamePos\": 216,\n                                    \"NameEnd\": 218\n                                  },\n                                  {\n                                    \"Name\": \"props\",\n                                    \"QuoteType\": 1,\n                                    \"NamePos\": 219,\n                                    \"NameEnd\": 224\n                                  }\n                                ]\n                              },\n                              \"Alias\": null\n                            },\n                            {\n                              \"Expr\": {\n                                \"LiteralPos\": 227,\n                                \"LiteralEnd\": 231,\n                                \"Literal\": \"arr2\"\n                              },\n                              \"Alias\": null\n                            }\n                          ]\n                        },\n                        \"ColumnArgList\": null\n                      }\n                    },\n                    \"Alias\": {\n                      \"Name\": \"a2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 237,\n                      \"NameEnd\": 239\n                    }\n                  }\n                ]\n              },\n              \"Right\": {\n                \"JoinPos\": 244,\n                \"Left\": {\n                  \"Table\": {\n                    \"TablePos\": 255,\n                    \"TableEnd\": 257,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Database\": null,\n                      \"Table\": {\n                        \"Name\": \"t3\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 255,\n                        \"NameEnd\": 257\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 257,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                },\n                \"Right\": null,\n                \"Modifiers\": [\n                  \"INNER\",\n                  \"JOIN\"\n                ],\n                \"Constraints\": {\n                  \"OnPos\": 258,\n                  \"On\": {\n                    \"ListPos\": 261,\n                    \"ListEnd\": 295,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"LeftExpr\": {\n                            \"Fields\": [\n                              {\n                                \"Name\": \"t3\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 261,\n                                \"NameEnd\": 263\n                              },\n                              {\n                                \"Name\": \"id\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 264,\n                                \"NameEnd\": 266\n                              }\n                            ]\n                          },\n                          \"Operation\": \"=\",\n                          \"RightExpr\": {\n                            \"Name\": {\n                              \"Name\": \"JSONExtractString\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 269,\n                              \"NameEnd\": 286\n                            },\n                            \"Params\": {\n                              \"LeftParenPos\": 286,\n                              \"RightParenPos\": 295,\n                              \"Items\": {\n                                \"ListPos\": 287,\n                                \"ListEnd\": 294,\n                                \"HasDistinct\": false,\n                                \"Items\": [\n                                  {\n                                    \"Expr\": {\n                                      \"Name\": \"a2\",\n                                      \"QuoteType\": 1,\n                                      \"NamePos\": 287,\n                                      \"NameEnd\": 289\n                                    },\n                                    \"Alias\": null\n                                  },\n                                  {\n                                    \"Expr\": {\n                                      \"LiteralPos\": 292,\n                                      \"LiteralEnd\": 294,\n                                      \"Literal\": \"id\"\n                                    },\n                                    \"Alias\": null\n                                  }\n                                ]\n                              },\n                              \"ColumnArgList\": null\n                            }\n                          },\n                          \"HasGlobal\": false,\n                          \"HasNot\": false\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  }\n                }\n              },\n              \"Modifiers\": [\n                \"ARRAY\",\n                \"JOIN\"\n              ],\n              \"Constraints\": null\n            },\n            \"Modifiers\": [\n              \"INNER\",\n              \"JOIN\"\n            ],\n            \"Constraints\": {\n              \"OnPos\": 142,\n              \"On\": {\n                \"ListPos\": 145,\n                \"ListEnd\": 179,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"LeftExpr\": {\n                        \"Fields\": [\n                          {\n                            \"Name\": \"t2\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 145,\n                            \"NameEnd\": 147\n                          },\n                          {\n                            \"Name\": \"id\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 148,\n                            \"NameEnd\": 150\n                          }\n                        ]\n                      },\n                      \"Operation\": \"=\",\n                      \"RightExpr\": {\n                        \"Name\": {\n                          \"Name\": \"JSONExtractString\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 153,\n                          \"NameEnd\": 170\n                        },\n                        \"Params\": {\n                          \"LeftParenPos\": 170,\n                          \"RightParenPos\": 179,\n                          \"Items\": {\n                            \"ListPos\": 171,\n                            \"ListEnd\": 178,\n                            \"HasDistinct\": false,\n                            \"Items\": [\n                              {\n                                \"Expr\": {\n                                  \"Name\": \"a1\",\n                                  \"QuoteType\": 1,\n                                  \"NamePos\": 171,\n                                  \"NameEnd\": 173\n                                },\n                                \"Alias\": null\n                              },\n                              {\n                                \"Expr\": {\n                                  \"LiteralPos\": 176,\n                                  \"LiteralEnd\": 178,\n                                  \"Literal\": \"id\"\n                                },\n                                \"Alias\": null\n                              }\n                            ]\n                          },\n                          \"ColumnArgList\": null\n                        }\n                      },\n                      \"HasGlobal\": false,\n                      \"HasNot\": false\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            }\n          },\n          \"Modifiers\": [\n            \"ARRAY\",\n            \"JOIN\"\n          ],\n          \"Constraints\": null\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 297,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Name\": \"value\",\n          \"QuoteType\": 1,\n          \"NamePos\": 303,\n          \"NameEnd\": 308\n        },\n        \"Operation\": \"!=\",\n        \"RightExpr\": {\n          \"LiteralPos\": 313,\n          \"LiteralEnd\": 313,\n          \"Literal\": \"\"\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_array_join.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 160,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"v\",\n          \"QuoteType\": 1,\n          \"NamePos\": 11,\n          \"NameEnd\": 12\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"j\",\n          \"QuoteType\": 1,\n          \"NamePos\": 18,\n          \"NameEnd\": 19\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 20,\n      \"Expr\": {\n        \"JoinPos\": 25,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 25,\n            \"TableEnd\": 27,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"t1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 25,\n                \"NameEnd\": 27\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 27,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 32,\n          \"Left\": {\n            \"ListPos\": 43,\n            \"ListEnd\": 70,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": {\n                    \"Name\": \"JSONExtractArrayRaw\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 43,\n                    \"NameEnd\": 62\n                  },\n                  \"Params\": {\n                    \"LeftParenPos\": 62,\n                    \"RightParenPos\": 64,\n                    \"Items\": {\n                      \"ListPos\": 63,\n                      \"ListEnd\": 64,\n                      \"HasDistinct\": false,\n                      \"Items\": [\n                        {\n                          \"Expr\": {\n                            \"Name\": \"a\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 63,\n                            \"NameEnd\": 64\n                          },\n                          \"Alias\": null\n                        }\n                      ]\n                    },\n                    \"ColumnArgList\": null\n                  }\n                },\n                \"Alias\": {\n                  \"Name\": \"j\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 69,\n                  \"NameEnd\": 70\n                }\n              }\n            ]\n          },\n          \"Right\": {\n            \"JoinPos\": 75,\n            \"Left\": {\n              \"ListPos\": 86,\n              \"ListEnd\": 160,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": {\n                      \"Name\": \"array\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 86,\n                      \"NameEnd\": 91\n                    },\n                    \"Params\": {\n                      \"LeftParenPos\": 91,\n                      \"RightParenPos\": 154,\n                      \"Items\": {\n                        \"ListPos\": 97,\n                        \"ListEnd\": 152,\n                        \"HasDistinct\": false,\n                        \"Items\": [\n                          {\n                            \"Expr\": {\n                              \"Name\": {\n                                \"Name\": \"JSONExtractString\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 97,\n                                \"NameEnd\": 114\n                              },\n                              \"Params\": {\n                                \"LeftParenPos\": 114,\n                                \"RightParenPos\": 121,\n                                \"Items\": {\n                                  \"ListPos\": 115,\n                                  \"ListEnd\": 120,\n                                  \"HasDistinct\": false,\n                                  \"Items\": [\n                                    {\n                                      \"Expr\": {\n                                        \"Name\": \"j\",\n                                        \"QuoteType\": 1,\n                                        \"NamePos\": 115,\n                                        \"NameEnd\": 116\n                                      },\n                                      \"Alias\": null\n                                    },\n                                    {\n                                      \"Expr\": {\n                                        \"LiteralPos\": 119,\n                                        \"LiteralEnd\": 120,\n                                        \"Literal\": \"x\"\n                                      },\n                                      \"Alias\": null\n                                    }\n                                  ]\n                                },\n                                \"ColumnArgList\": null\n                              }\n                            },\n                            \"Alias\": null\n                          },\n                          {\n                            \"Expr\": {\n                              \"Name\": {\n                                \"Name\": \"JSONExtractString\",\n                                \"QuoteType\": 1,\n                                \"NamePos\": 128,\n                                \"NameEnd\": 145\n                              },\n                              \"Params\": {\n                                \"LeftParenPos\": 145,\n                                \"RightParenPos\": 152,\n                                \"Items\": {\n                                  \"ListPos\": 146,\n                                  \"ListEnd\": 151,\n                                  \"HasDistinct\": false,\n                                  \"Items\": [\n                                    {\n                                      \"Expr\": {\n                                        \"Name\": \"j\",\n                                        \"QuoteType\": 1,\n                                        \"NamePos\": 146,\n                                        \"NameEnd\": 147\n                                      },\n                                      \"Alias\": null\n                                    },\n                                    {\n                                      \"Expr\": {\n                                        \"LiteralPos\": 150,\n                                        \"LiteralEnd\": 151,\n                                        \"Literal\": \"y\"\n                                      },\n                                      \"Alias\": null\n                                    }\n                                  ]\n                                },\n                                \"ColumnArgList\": null\n                              }\n                            },\n                            \"Alias\": null\n                          }\n                        ]\n                      },\n                      \"ColumnArgList\": null\n                    }\n                  },\n                  \"Alias\": {\n                    \"Name\": \"v\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 159,\n                    \"NameEnd\": 160\n                  }\n                }\n              ]\n            },\n            \"Right\": null,\n            \"Modifiers\": [\n              \"ARRAY\",\n              \"JOIN\"\n            ],\n            \"Constraints\": null\n          },\n          \"Modifiers\": [\n            \"ARRAY\",\n            \"JOIN\"\n          ],\n          \"Constraints\": null\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_except.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 32,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"number\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 13\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 14,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 19,\n          \"TableEnd\": 32,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Name\": {\n              \"Name\": \"numbers\",\n              \"QuoteType\": 1,\n              \"NamePos\": 19,\n              \"NameEnd\": 26\n            },\n            \"Args\": {\n              \"LeftParenPos\": 26,\n              \"RightParenPos\": 32,\n              \"Args\": [\n                {\n                  \"NumPos\": 27,\n                  \"NumEnd\": 28,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                {\n                  \"NumPos\": 30,\n                  \"NumEnd\": 32,\n                  \"Literal\": \"10\",\n                  \"Base\": 10\n                }\n              ]\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 32,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": {\n      \"SelectPos\": 41,\n      \"StatementEnd\": 72,\n      \"With\": null,\n      \"Top\": null,\n      \"HasDistinct\": false,\n      \"DistinctOn\": null,\n      \"SelectItems\": [\n        {\n          \"Expr\": {\n            \"Name\": \"number\",\n            \"QuoteType\": 1,\n            \"NamePos\": 48,\n            \"NameEnd\": 54\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        }\n      ],\n      \"From\": {\n        \"FromPos\": 55,\n        \"Expr\": {\n          \"Table\": {\n            \"TablePos\": 60,\n            \"TableEnd\": 72,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Name\": {\n                \"Name\": \"numbers\",\n                \"QuoteType\": 1,\n                \"NamePos\": 60,\n                \"NameEnd\": 67\n              },\n              \"Args\": {\n                \"LeftParenPos\": 67,\n                \"RightParenPos\": 72,\n                \"Args\": [\n                  {\n                    \"NumPos\": 68,\n                    \"NumEnd\": 69,\n                    \"Literal\": \"3\",\n                    \"Base\": 10\n                  },\n                  {\n                    \"NumPos\": 71,\n                    \"NumEnd\": 72,\n                    \"Literal\": \"6\",\n                    \"Base\": 10\n                  }\n                ]\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 72,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        }\n      },\n      \"Window\": null,\n      \"Prewhere\": null,\n      \"Where\": null,\n      \"GroupBy\": null,\n      \"WithTotal\": false,\n      \"Having\": null,\n      \"OrderBy\": null,\n      \"LimitBy\": null,\n      \"Limit\": null,\n      \"Settings\": null,\n      \"Format\": null,\n      \"UnionAll\": null,\n      \"UnionDistinct\": null,\n      \"Except\": {\n        \"SelectPos\": 81,\n        \"StatementEnd\": 112,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"Name\": \"number\",\n              \"QuoteType\": 1,\n              \"NamePos\": 88,\n              \"NameEnd\": 94\n            },\n            \"Modifiers\": [],\n            \"Alias\": null\n          }\n        ],\n        \"From\": {\n          \"FromPos\": 95,\n          \"Expr\": {\n            \"Table\": {\n              \"TablePos\": 100,\n              \"TableEnd\": 112,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Name\": {\n                  \"Name\": \"numbers\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 100,\n                  \"NameEnd\": 107\n                },\n                \"Args\": {\n                  \"LeftParenPos\": 107,\n                  \"RightParenPos\": 112,\n                  \"Args\": [\n                    {\n                      \"NumPos\": 108,\n                      \"NumEnd\": 109,\n                      \"Literal\": \"8\",\n                      \"Base\": 10\n                    },\n                    {\n                      \"NumPos\": 111,\n                      \"NumEnd\": 112,\n                      \"Literal\": \"9\",\n                      \"Base\": 10\n                    }\n                  ]\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 112,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          }\n        },\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      }\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_join.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 297,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 91,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 5,\n          \"Expr\": {\n            \"Name\": \"t1\",\n            \"QuoteType\": 1,\n            \"NamePos\": 5,\n            \"NameEnd\": 7\n          },\n          \"Alias\": {\n            \"SelectPos\": 17,\n            \"StatementEnd\": 41,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"LiteralPos\": 25,\n                  \"LiteralEnd\": 31,\n                  \"Literal\": \"value1\"\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"value\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 36,\n                  \"NameEnd\": 41\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        },\n        {\n          \"CTEPos\": 49,\n          \"Expr\": {\n            \"Name\": \"t2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 49,\n            \"NameEnd\": 51\n          },\n          \"Alias\": {\n            \"SelectPos\": 57,\n            \"StatementEnd\": 81,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"LiteralPos\": 65,\n                  \"LiteralEnd\": 71,\n                  \"Literal\": \"value2\"\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"value\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 76,\n                  \"NameEnd\": 81\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        },\n        {\n          \"CTEPos\": 89,\n          \"Expr\": {\n            \"Name\": \"t3\",\n            \"QuoteType\": 1,\n            \"NamePos\": 89,\n            \"NameEnd\": 91\n          },\n          \"Alias\": {\n            \"SelectPos\": 97,\n            \"StatementEnd\": 121,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"LiteralPos\": 105,\n                  \"LiteralEnd\": 111,\n                  \"Literal\": \"value3\"\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"value\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 116,\n                  \"NameEnd\": 121\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t1\",\n              \"QuoteType\": 1,\n              \"NamePos\": 139,\n              \"NameEnd\": 141\n            },\n            {\n              \"Name\": \"value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 142,\n              \"NameEnd\": 147\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 151,\n          \"NameEnd\": 157\n        }\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t2\",\n              \"QuoteType\": 1,\n              \"NamePos\": 163,\n              \"NameEnd\": 165\n            },\n            {\n              \"Name\": \"value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 166,\n              \"NameEnd\": 171\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 175,\n          \"NameEnd\": 181\n        }\n      },\n      {\n        \"Expr\": {\n          \"Fields\": [\n            {\n              \"Name\": \"t3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 187,\n              \"NameEnd\": 189\n            },\n            {\n              \"Name\": \"value\",\n              \"QuoteType\": 1,\n              \"NamePos\": 190,\n              \"NameEnd\": 195\n            }\n          ]\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"value3\",\n          \"QuoteType\": 1,\n          \"NamePos\": 199,\n          \"NameEnd\": 205\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 206,\n      \"Expr\": {\n        \"JoinPos\": 215,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 215,\n            \"TableEnd\": 217,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"t1\",\n                \"QuoteType\": 1,\n                \"NamePos\": 215,\n                \"NameEnd\": 217\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 217,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 226,\n          \"Left\": {\n            \"Table\": {\n              \"TablePos\": 231,\n              \"TableEnd\": 233,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Database\": null,\n                \"Table\": {\n                  \"Name\": \"t2\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 231,\n                  \"NameEnd\": 233\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 233,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Right\": {\n            \"JoinPos\": 250,\n            \"Left\": {\n              \"Table\": {\n                \"TablePos\": 255,\n                \"TableEnd\": 257,\n                \"Alias\": null,\n                \"Expr\": {\n                  \"Database\": null,\n                  \"Table\": {\n                    \"Name\": \"t3\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 255,\n                    \"NameEnd\": 257\n                  }\n                },\n                \"HasFinal\": false\n              },\n              \"StatementEnd\": 257,\n              \"SampleRatio\": null,\n              \"HasFinal\": false\n            },\n            \"Right\": {\n              \"JoinPos\": 266,\n              \"Left\": {\n                \"Table\": {\n                  \"TablePos\": 271,\n                  \"TableEnd\": 273,\n                  \"Alias\": null,\n                  \"Expr\": {\n                    \"Database\": null,\n                    \"Table\": {\n                      \"Name\": \"t4\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 271,\n                      \"NameEnd\": 273\n                    }\n                  },\n                  \"HasFinal\": false\n                },\n                \"StatementEnd\": 273,\n                \"SampleRatio\": null,\n                \"HasFinal\": false\n              },\n              \"Right\": {\n                \"JoinPos\": 290,\n                \"Left\": {\n                  \"Table\": {\n                    \"TablePos\": 295,\n                    \"TableEnd\": 297,\n                    \"Alias\": null,\n                    \"Expr\": {\n                      \"Database\": null,\n                      \"Table\": {\n                        \"Name\": \"t5\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 295,\n                        \"NameEnd\": 297\n                      }\n                    },\n                    \"HasFinal\": false\n                  },\n                  \"StatementEnd\": 297,\n                  \"SampleRatio\": null,\n                  \"HasFinal\": false\n                },\n                \"Right\": null,\n                \"Modifiers\": [\n                  \"JOIN\"\n                ],\n                \"Constraints\": null\n              },\n              \"Modifiers\": [\n                \"JOIN\"\n              ],\n              \"Constraints\": {\n                \"OnPos\": 274,\n                \"On\": {\n                  \"ListPos\": 277,\n                  \"ListEnd\": 281,\n                  \"HasDistinct\": false,\n                  \"Items\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"true\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 277,\n                        \"NameEnd\": 281\n                      },\n                      \"Alias\": null\n                    }\n                  ]\n                }\n              }\n            },\n            \"Modifiers\": [\n              \"JOIN\"\n            ],\n            \"Constraints\": null\n          },\n          \"Modifiers\": [\n            \"JOIN\"\n          ],\n          \"Constraints\": {\n            \"OnPos\": 234,\n            \"On\": {\n              \"ListPos\": 237,\n              \"ListEnd\": 241,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"Name\": \"true\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 237,\n                    \"NameEnd\": 241\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_line_comment.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 61,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 48,\n          \"NameEnd\": 48\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 50,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 59,\n          \"TableEnd\": 61,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 59,\n              \"NameEnd\": 61\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 61,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_union.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 14,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 7,\n          \"NumEnd\": 8,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"v1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 12,\n          \"NameEnd\": 14\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": {\n      \"SelectPos\": 25,\n      \"StatementEnd\": 39,\n      \"With\": null,\n      \"Top\": null,\n      \"HasDistinct\": false,\n      \"DistinctOn\": null,\n      \"SelectItems\": [\n        {\n          \"Expr\": {\n            \"NumPos\": 32,\n            \"NumEnd\": 33,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          },\n          \"Modifiers\": [],\n          \"Alias\": {\n            \"Name\": \"v2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 37,\n            \"NameEnd\": 39\n          }\n        }\n      ],\n      \"From\": null,\n      \"Window\": null,\n      \"Prewhere\": null,\n      \"Where\": null,\n      \"GroupBy\": null,\n      \"WithTotal\": false,\n      \"Having\": null,\n      \"OrderBy\": null,\n      \"LimitBy\": null,\n      \"Limit\": null,\n      \"Settings\": null,\n      \"Format\": null,\n      \"UnionAll\": {\n        \"SelectPos\": 50,\n        \"StatementEnd\": 64,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"NumPos\": 57,\n              \"NumEnd\": 58,\n              \"Literal\": \"3\",\n              \"Base\": 10\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"v3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 62,\n              \"NameEnd\": 64\n            }\n          }\n        ],\n        \"From\": null,\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      },\n      \"UnionDistinct\": null,\n      \"Except\": null\n    },\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_multi_union_distinct.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 14,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 7,\n          \"NumEnd\": 8,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"v1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 12,\n          \"NameEnd\": 14\n        }\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": {\n      \"SelectPos\": 30,\n      \"StatementEnd\": 44,\n      \"With\": null,\n      \"Top\": null,\n      \"HasDistinct\": false,\n      \"DistinctOn\": null,\n      \"SelectItems\": [\n        {\n          \"Expr\": {\n            \"NumPos\": 37,\n            \"NumEnd\": 38,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          },\n          \"Modifiers\": [],\n          \"Alias\": {\n            \"Name\": \"v2\",\n            \"QuoteType\": 1,\n            \"NamePos\": 42,\n            \"NameEnd\": 44\n          }\n        }\n      ],\n      \"From\": null,\n      \"Window\": null,\n      \"Prewhere\": null,\n      \"Where\": null,\n      \"GroupBy\": null,\n      \"WithTotal\": false,\n      \"Having\": null,\n      \"OrderBy\": null,\n      \"LimitBy\": null,\n      \"Limit\": null,\n      \"Settings\": null,\n      \"Format\": null,\n      \"UnionAll\": null,\n      \"UnionDistinct\": {\n        \"SelectPos\": 60,\n        \"StatementEnd\": 74,\n        \"With\": null,\n        \"Top\": null,\n        \"HasDistinct\": false,\n        \"DistinctOn\": null,\n        \"SelectItems\": [\n          {\n            \"Expr\": {\n              \"NumPos\": 67,\n              \"NumEnd\": 68,\n              \"Literal\": \"3\",\n              \"Base\": 10\n            },\n            \"Modifiers\": [],\n            \"Alias\": {\n              \"Name\": \"v3\",\n              \"QuoteType\": 1,\n              \"NamePos\": 72,\n              \"NameEnd\": 74\n            }\n          }\n        ],\n        \"From\": null,\n        \"Window\": null,\n        \"Prewhere\": null,\n        \"Where\": null,\n        \"GroupBy\": null,\n        \"WithTotal\": false,\n        \"Having\": null,\n        \"OrderBy\": null,\n        \"LimitBy\": null,\n        \"Limit\": null,\n        \"Settings\": null,\n        \"Format\": null,\n        \"UnionAll\": null,\n        \"UnionDistinct\": null,\n        \"Except\": null\n      },\n      \"Except\": null\n    },\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_number_field.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 53,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"foo\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"Name\": \"bar\",\n            \"QuoteType\": 1,\n            \"NamePos\": 12,\n            \"NameEnd\": 15\n          },\n          \"Operation\": \".\",\n          \"Index\": {\n            \"NumPos\": 16,\n            \"NumEnd\": 17,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Object\": {\n            \"Name\": \"foo\",\n            \"QuoteType\": 1,\n            \"NamePos\": 19,\n            \"NameEnd\": 22\n          },\n          \"Operation\": \".\",\n          \"Index\": {\n            \"NumPos\": 23,\n            \"NumEnd\": 24,\n            \"Literal\": \"2\",\n            \"Base\": 10\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 25,\n      \"Expr\": {\n        \"JoinPos\": 30,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 30,\n            \"TableEnd\": 33,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": null,\n              \"Table\": {\n                \"Name\": \"foo\",\n                \"QuoteType\": 1,\n                \"NamePos\": 30,\n                \"NameEnd\": 33\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 33,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 34,\n          \"Left\": {\n            \"ListPos\": 45,\n            \"ListEnd\": 53,\n            \"HasDistinct\": false,\n            \"Items\": [\n              {\n                \"Expr\": {\n                  \"Name\": \"m\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 45,\n                  \"NameEnd\": 46\n                },\n                \"Alias\": {\n                  \"Name\": \"bar\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 50,\n                  \"NameEnd\": 53\n                }\n              }\n            ]\n          },\n          \"Right\": null,\n          \"Modifiers\": [\n            \"ARRAY\",\n            \"JOIN\"\n          ],\n          \"Constraints\": null\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_placeholder.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 28,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 7,\n          \"NameEnd\": 7\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 9,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 14,\n          \"TableEnd\": 16,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 14,\n              \"NameEnd\": 16\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 16,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 17,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Name\": \"id\",\n          \"QuoteType\": 1,\n          \"NamePos\": 23,\n          \"NameEnd\": 25\n        },\n        \"Operation\": \"=\",\n        \"RightExpr\": {\n          \"PlaceholderPos\": 28,\n          \"PlaceHolderEnd\": 28,\n          \"Type\": \"?\"\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_query_parameter.sql.golden.json",
    "content": "[\n  {\n    \"SetPos\": 0,\n    \"Settings\": {\n      \"SettingsPos\": 4,\n      \"ListEnd\": 16,\n      \"Items\": [\n        {\n          \"SettingsPos\": 4,\n          \"Name\": {\n            \"Name\": \"param_a\",\n            \"QuoteType\": 1,\n            \"NamePos\": 4,\n            \"NameEnd\": 11\n          },\n          \"Expr\": {\n            \"NumPos\": 14,\n            \"NumEnd\": 16,\n            \"Literal\": \"13\",\n            \"Base\": 10\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 18,\n    \"Settings\": {\n      \"SettingsPos\": 22,\n      \"ListEnd\": 36,\n      \"Items\": [\n        {\n          \"SettingsPos\": 22,\n          \"Name\": {\n            \"Name\": \"param_b\",\n            \"QuoteType\": 1,\n            \"NamePos\": 22,\n            \"NameEnd\": 29\n          },\n          \"Expr\": {\n            \"LiteralPos\": 33,\n            \"LiteralEnd\": 36,\n            \"Literal\": \"str\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 39,\n    \"Settings\": {\n      \"SettingsPos\": 43,\n      \"ListEnd\": 73,\n      \"Items\": [\n        {\n          \"SettingsPos\": 43,\n          \"Name\": {\n            \"Name\": \"param_c\",\n            \"QuoteType\": 1,\n            \"NamePos\": 43,\n            \"NameEnd\": 50\n          },\n          \"Expr\": {\n            \"LiteralPos\": 54,\n            \"LiteralEnd\": 73,\n            \"Literal\": \"2022-08-04 18:30:53\"\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SetPos\": 76,\n    \"Settings\": {\n      \"SettingsPos\": 80,\n      \"ListEnd\": 121,\n      \"Items\": [\n        {\n          \"SettingsPos\": 80,\n          \"Name\": {\n            \"Name\": \"param_d\",\n            \"QuoteType\": 1,\n            \"NamePos\": 80,\n            \"NameEnd\": 87\n          },\n          \"Expr\": {\n            \"LBracePos\": 90,\n            \"RBracePos\": 121,\n            \"KeyValues\": [\n              {\n                \"Key\": {\n                  \"LiteralPos\": 92,\n                  \"LiteralEnd\": 94,\n                  \"Literal\": \"10\"\n                },\n                \"Value\": {\n                  \"LeftBracketPos\": 97,\n                  \"RightBracketPos\": 104,\n                  \"Items\": {\n                    \"ListPos\": 98,\n                    \"ListEnd\": 104,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"NumPos\": 98,\n                          \"NumEnd\": 100,\n                          \"Literal\": \"11\",\n                          \"Base\": 10\n                        },\n                        \"Alias\": null\n                      },\n                      {\n                        \"Expr\": {\n                          \"NumPos\": 102,\n                          \"NumEnd\": 104,\n                          \"Literal\": \"12\",\n                          \"Base\": 10\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  }\n                }\n              },\n              {\n                \"Key\": {\n                  \"LiteralPos\": 108,\n                  \"LiteralEnd\": 110,\n                  \"Literal\": \"13\"\n                },\n                \"Value\": {\n                  \"LeftBracketPos\": 113,\n                  \"RightBracketPos\": 120,\n                  \"Items\": {\n                    \"ListPos\": 114,\n                    \"ListEnd\": 120,\n                    \"HasDistinct\": false,\n                    \"Items\": [\n                      {\n                        \"Expr\": {\n                          \"NumPos\": 114,\n                          \"NumEnd\": 116,\n                          \"Literal\": \"14\",\n                          \"Base\": 10\n                        },\n                        \"Alias\": null\n                      },\n                      {\n                        \"Expr\": {\n                          \"NumPos\": 118,\n                          \"NumEnd\": 120,\n                          \"Literal\": \"15\",\n                          \"Base\": 10\n                        },\n                        \"Alias\": null\n                      }\n                    ]\n                  }\n                }\n              }\n            ]\n          }\n        }\n      ]\n    }\n  },\n  {\n    \"SelectPos\": 125,\n    \"StatementEnd\": 218,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LBracePos\": 136,\n          \"RBracePos\": 146,\n          \"Name\": {\n            \"Name\": \"a\",\n            \"QuoteType\": 1,\n            \"NamePos\": 137,\n            \"NameEnd\": 138\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt32\",\n              \"QuoteType\": 1,\n              \"NamePos\": 140,\n              \"NameEnd\": 146\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"LBracePos\": 153,\n          \"RBracePos\": 163,\n          \"Name\": {\n            \"Name\": \"b\",\n            \"QuoteType\": 1,\n            \"NamePos\": 154,\n            \"NameEnd\": 155\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 157,\n              \"NameEnd\": 163\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"LBracePos\": 170,\n          \"RBracePos\": 182,\n          \"Name\": {\n            \"Name\": \"c\",\n            \"QuoteType\": 1,\n            \"NamePos\": 171,\n            \"NameEnd\": 172\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"DateTime\",\n              \"QuoteType\": 1,\n              \"NamePos\": 174,\n              \"NameEnd\": 182\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"LBracePos\": 189,\n          \"RBracePos\": 218,\n          \"Name\": {\n            \"Name\": \"d\",\n            \"QuoteType\": 1,\n            \"NamePos\": 190,\n            \"NameEnd\": 191\n          },\n          \"Type\": {\n            \"LeftParenPos\": 197,\n            \"RightParenPos\": 217,\n            \"Name\": {\n              \"Name\": \"Map\",\n              \"QuoteType\": 1,\n              \"NamePos\": 193,\n              \"NameEnd\": 196\n            },\n            \"Params\": [\n              {\n                \"Name\": {\n                  \"Name\": \"String\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 197,\n                  \"NameEnd\": 203\n                }\n              },\n              {\n                \"LeftParenPos\": 211,\n                \"RightParenPos\": 216,\n                \"Name\": {\n                  \"Name\": \"Array\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 205,\n                  \"NameEnd\": 210\n                },\n                \"Params\": [\n                  {\n                    \"Name\": {\n                      \"Name\": \"UInt8\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 211,\n                      \"NameEnd\": 216\n                    }\n                  }\n                ]\n              }\n            ]\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 222,\n    \"StatementEnd\": 283,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 229,\n          \"NameEnd\": 229\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 231,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 236,\n          \"TableEnd\": 246,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"clickhouse\",\n              \"QuoteType\": 1,\n              \"NamePos\": 236,\n              \"NameEnd\": 246\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 246,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 247,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"Name\": \"tenant_id\",\n          \"QuoteType\": 1,\n          \"NamePos\": 253,\n          \"NameEnd\": 262\n        },\n        \"Operation\": \"=\",\n        \"RightExpr\": {\n          \"LBracePos\": 265,\n          \"RBracePos\": 283,\n          \"Name\": {\n            \"Name\": \"tenant_id\",\n            \"QuoteType\": 1,\n            \"NamePos\": 266,\n            \"NameEnd\": 275\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"String\",\n              \"QuoteType\": 1,\n              \"NamePos\": 277,\n              \"NameEnd\": 283\n            }\n          }\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_settings_additional_table_filters.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 86,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 7,\n          \"NameEnd\": 7\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 9,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 14,\n          \"TableEnd\": 24,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"test_table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 14,\n              \"NameEnd\": 24\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 24,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": {\n      \"SettingsPos\": 25,\n      \"ListEnd\": 86,\n      \"Items\": [\n        {\n          \"SettingsPos\": 34,\n          \"Name\": {\n            \"Name\": \"additional_table_filters\",\n            \"QuoteType\": 1,\n            \"NamePos\": 34,\n            \"NameEnd\": 58\n          },\n          \"Expr\": {\n            \"LBracePos\": 59,\n            \"RBracePos\": 86,\n            \"KeyValues\": [\n              {\n                \"Key\": {\n                  \"LiteralPos\": 61,\n                  \"LiteralEnd\": 71,\n                  \"Literal\": \"test_table\"\n                },\n                \"Value\": {\n                  \"LiteralPos\": 75,\n                  \"LiteralEnd\": 85,\n                  \"Literal\": \"status = 1\"\n                }\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 90,\n    \"StatementEnd\": 182,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 97,\n          \"NameEnd\": 97\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 99,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 104,\n          \"TableEnd\": 114,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"test_table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 104,\n              \"NameEnd\": 114\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 114,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": {\n      \"SettingsPos\": 115,\n      \"ListEnd\": 182,\n      \"Items\": [\n        {\n          \"SettingsPos\": 124,\n          \"Name\": {\n            \"Name\": \"additional_table_filters\",\n            \"QuoteType\": 1,\n            \"NamePos\": 124,\n            \"NameEnd\": 148\n          },\n          \"Expr\": {\n            \"LBracePos\": 149,\n            \"RBracePos\": 182,\n            \"KeyValues\": [\n              {\n                \"Key\": {\n                  \"LiteralPos\": 151,\n                  \"LiteralEnd\": 161,\n                  \"Literal\": \"test_table\"\n                },\n                \"Value\": {\n                  \"LiteralPos\": 165,\n                  \"LiteralEnd\": 181,\n                  \"Literal\": \"value = \\\\'test\\\\'\"\n                }\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 186,\n    \"StatementEnd\": 278,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 193,\n          \"NameEnd\": 193\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 195,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 200,\n          \"TableEnd\": 210,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"test_table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 200,\n              \"NameEnd\": 210\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 210,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": {\n      \"SettingsPos\": 211,\n      \"ListEnd\": 278,\n      \"Items\": [\n        {\n          \"SettingsPos\": 220,\n          \"Name\": {\n            \"Name\": \"additional_table_filters\",\n            \"QuoteType\": 1,\n            \"NamePos\": 220,\n            \"NameEnd\": 244\n          },\n          \"Expr\": {\n            \"LBracePos\": 245,\n            \"RBracePos\": 278,\n            \"KeyValues\": [\n              {\n                \"Key\": {\n                  \"LiteralPos\": 247,\n                  \"LiteralEnd\": 257,\n                  \"Literal\": \"test_table\"\n                },\n                \"Value\": {\n                  \"LiteralPos\": 261,\n                  \"LiteralEnd\": 277,\n                  \"Literal\": \"value = ''test''\"\n                }\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 282,\n    \"StatementEnd\": 415,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 289,\n          \"NameEnd\": 289\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 291,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 296,\n          \"TableEnd\": 306,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"test_table\",\n              \"QuoteType\": 1,\n              \"NamePos\": 296,\n              \"NameEnd\": 306\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 306,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": {\n      \"SettingsPos\": 307,\n      \"ListEnd\": 402,\n      \"Items\": [\n        {\n          \"SettingsPos\": 316,\n          \"Name\": {\n            \"Name\": \"additional_table_filters\",\n            \"QuoteType\": 1,\n            \"NamePos\": 316,\n            \"NameEnd\": 340\n          },\n          \"Expr\": {\n            \"LBracePos\": 341,\n            \"RBracePos\": 402,\n            \"KeyValues\": [\n              {\n                \"Key\": {\n                  \"LiteralPos\": 343,\n                  \"LiteralEnd\": 353,\n                  \"Literal\": \"test_table\"\n                },\n                \"Value\": {\n                  \"LiteralPos\": 357,\n                  \"LiteralEnd\": 401,\n                  \"Literal\": \"id IN (\\\\'a\\\\', \\\\'b\\\\') AND status = \\\\'active\\\\'\"\n                }\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"Format\": {\n      \"FormatPos\": 404,\n      \"Format\": {\n        \"Name\": \"JSON\",\n        \"QuoteType\": 1,\n        \"NamePos\": 411,\n        \"NameEnd\": 415\n      }\n    },\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 418,\n    \"StatementEnd\": 635,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"number\",\n          \"QuoteType\": 1,\n          \"NamePos\": 425,\n          \"NameEnd\": 431\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"x\",\n          \"QuoteType\": 1,\n          \"NamePos\": 433,\n          \"NameEnd\": 434\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"y\",\n          \"QuoteType\": 1,\n          \"NamePos\": 436,\n          \"NameEnd\": 437\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 438,\n      \"Expr\": {\n        \"JoinPos\": 443,\n        \"Left\": {\n          \"Table\": {\n            \"TablePos\": 443,\n            \"TableEnd\": 488,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Expr\": {\n                \"HasParen\": true,\n                \"Select\": {\n                  \"SelectPos\": 444,\n                  \"StatementEnd\": 485,\n                  \"With\": null,\n                  \"Top\": null,\n                  \"HasDistinct\": false,\n                  \"DistinctOn\": null,\n                  \"SelectItems\": [\n                    {\n                      \"Expr\": {\n                        \"Name\": \"number\",\n                        \"QuoteType\": 1,\n                        \"NamePos\": 451,\n                        \"NameEnd\": 457\n                      },\n                      \"Modifiers\": [],\n                      \"Alias\": null\n                    }\n                  ],\n                  \"From\": {\n                    \"FromPos\": 458,\n                    \"Expr\": {\n                      \"Table\": {\n                        \"TablePos\": 463,\n                        \"TableEnd\": 477,\n                        \"Alias\": null,\n                        \"Expr\": {\n                          \"Database\": {\n                            \"Name\": \"system\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 463,\n                            \"NameEnd\": 469\n                          },\n                          \"Table\": {\n                            \"Name\": \"numbers\",\n                            \"QuoteType\": 1,\n                            \"NamePos\": 470,\n                            \"NameEnd\": 477\n                          }\n                        },\n                        \"HasFinal\": false\n                      },\n                      \"StatementEnd\": 477,\n                      \"SampleRatio\": null,\n                      \"HasFinal\": false\n                    }\n                  },\n                  \"Window\": null,\n                  \"Prewhere\": null,\n                  \"Where\": null,\n                  \"GroupBy\": null,\n                  \"WithTotal\": false,\n                  \"Having\": null,\n                  \"OrderBy\": null,\n                  \"LimitBy\": null,\n                  \"Limit\": {\n                    \"LimitPos\": 478,\n                    \"Limit\": {\n                      \"NumPos\": 484,\n                      \"NumEnd\": 485,\n                      \"Literal\": \"5\",\n                      \"Base\": 10\n                    },\n                    \"Offset\": null\n                  },\n                  \"Settings\": null,\n                  \"Format\": null,\n                  \"UnionAll\": null,\n                  \"UnionDistinct\": null,\n                  \"Except\": null\n                }\n              },\n              \"AliasPos\": 487,\n              \"Alias\": {\n                \"Name\": \"f\",\n                \"QuoteType\": 1,\n                \"NamePos\": 487,\n                \"NameEnd\": 488\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 488,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        },\n        \"Right\": {\n          \"JoinPos\": 489,\n          \"Left\": {\n            \"Table\": {\n              \"TablePos\": 503,\n              \"TableEnd\": 531,\n              \"Alias\": null,\n              \"Expr\": {\n                \"Expr\": {\n                  \"HasParen\": true,\n                  \"Select\": {\n                    \"SelectPos\": 504,\n                    \"StatementEnd\": 528,\n                    \"With\": null,\n                    \"Top\": null,\n                    \"HasDistinct\": false,\n                    \"DistinctOn\": null,\n                    \"SelectItems\": [\n                      {\n                        \"Expr\": {\n                          \"Name\": \"x\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 511,\n                          \"NameEnd\": 512\n                        },\n                        \"Modifiers\": [],\n                        \"Alias\": null\n                      },\n                      {\n                        \"Expr\": {\n                          \"Name\": \"y\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 514,\n                          \"NameEnd\": 515\n                        },\n                        \"Modifiers\": [],\n                        \"Alias\": null\n                      }\n                    ],\n                    \"From\": {\n                      \"FromPos\": 516,\n                      \"Expr\": {\n                        \"Table\": {\n                          \"TablePos\": 521,\n                          \"TableEnd\": 528,\n                          \"Alias\": null,\n                          \"Expr\": {\n                            \"Database\": null,\n                            \"Table\": {\n                              \"Name\": \"table_1\",\n                              \"QuoteType\": 1,\n                              \"NamePos\": 521,\n                              \"NameEnd\": 528\n                            }\n                          },\n                          \"HasFinal\": false\n                        },\n                        \"StatementEnd\": 528,\n                        \"SampleRatio\": null,\n                        \"HasFinal\": false\n                      }\n                    },\n                    \"Window\": null,\n                    \"Prewhere\": null,\n                    \"Where\": null,\n                    \"GroupBy\": null,\n                    \"WithTotal\": false,\n                    \"Having\": null,\n                    \"OrderBy\": null,\n                    \"LimitBy\": null,\n                    \"Limit\": null,\n                    \"Settings\": null,\n                    \"Format\": null,\n                    \"UnionAll\": null,\n                    \"UnionDistinct\": null,\n                    \"Except\": null\n                  }\n                },\n                \"AliasPos\": 530,\n                \"Alias\": {\n                  \"Name\": \"s\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 530,\n                  \"NameEnd\": 531\n                }\n              },\n              \"HasFinal\": false\n            },\n            \"StatementEnd\": 531,\n            \"SampleRatio\": null,\n            \"HasFinal\": false\n          },\n          \"Right\": null,\n          \"Modifiers\": [\n            \"ANY\",\n            \"LEFT\",\n            \"JOIN\"\n          ],\n          \"Constraints\": {\n            \"OnPos\": 532,\n            \"On\": {\n              \"ListPos\": 535,\n              \"ListEnd\": 549,\n              \"HasDistinct\": false,\n              \"Items\": [\n                {\n                  \"Expr\": {\n                    \"LeftExpr\": {\n                      \"Fields\": [\n                        {\n                          \"Name\": \"f\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 535,\n                          \"NameEnd\": 536\n                        },\n                        {\n                          \"Name\": \"number\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 537,\n                          \"NameEnd\": 543\n                        }\n                      ]\n                    },\n                    \"Operation\": \"=\",\n                    \"RightExpr\": {\n                      \"Fields\": [\n                        {\n                          \"Name\": \"s\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 546,\n                          \"NameEnd\": 547\n                        },\n                        {\n                          \"Name\": \"x\",\n                          \"QuoteType\": 1,\n                          \"NamePos\": 548,\n                          \"NameEnd\": 549\n                        }\n                      ]\n                    },\n                    \"HasGlobal\": false,\n                    \"HasNot\": false\n                  },\n                  \"Alias\": null\n                }\n              ]\n            }\n          }\n        },\n        \"Modifiers\": null,\n        \"Constraints\": null\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": {\n      \"SettingsPos\": 550,\n      \"ListEnd\": 635,\n      \"Items\": [\n        {\n          \"SettingsPos\": 559,\n          \"Name\": {\n            \"Name\": \"additional_table_filters\",\n            \"QuoteType\": 1,\n            \"NamePos\": 559,\n            \"NameEnd\": 583\n          },\n          \"Expr\": {\n            \"LBracePos\": 584,\n            \"RBracePos\": 635,\n            \"KeyValues\": [\n              {\n                \"Key\": {\n                  \"LiteralPos\": 586,\n                  \"LiteralEnd\": 600,\n                  \"Literal\": \"system.numbers\"\n                },\n                \"Value\": {\n                  \"LiteralPos\": 603,\n                  \"LiteralEnd\": 614,\n                  \"Literal\": \"number != 3\"\n                }\n              },\n              {\n                \"Key\": {\n                  \"LiteralPos\": 618,\n                  \"LiteralEnd\": 625,\n                  \"Literal\": \"table_1\"\n                },\n                \"Value\": {\n                  \"LiteralPos\": 628,\n                  \"LiteralEnd\": 634,\n                  \"Literal\": \"x != 2\"\n                }\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_single_quote_table.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 25,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 7,\n          \"NameEnd\": 7\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 9,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 15,\n          \"TableEnd\": 25,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"test_table\",\n              \"QuoteType\": 4,\n              \"NamePos\": 15,\n              \"NameEnd\": 25\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 25,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_string_expr.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 48,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 9,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 6,\n          \"Expr\": {\n            \"Name\": \"abc\",\n            \"QuoteType\": 2,\n            \"NamePos\": 6,\n            \"NameEnd\": 9\n          },\n          \"Alias\": {\n            \"SelectPos\": 15,\n            \"StatementEnd\": 28,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"NumPos\": 22,\n                  \"NumEnd\": 23,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"a\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 27,\n                  \"NameEnd\": 28\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 37,\n          \"NameEnd\": 37\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 39,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 45,\n          \"TableEnd\": 48,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"abc\",\n              \"QuoteType\": 2,\n              \"NamePos\": 45,\n              \"NameEnd\": 48\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 48,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_union_distinct.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 43,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"replica_name\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 19\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 20,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 25,\n          \"TableEnd\": 43,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": {\n              \"Name\": \"system\",\n              \"QuoteType\": 1,\n              \"NamePos\": 25,\n              \"NameEnd\": 31\n            },\n            \"Table\": {\n              \"Name\": \"ha_replicas\",\n              \"QuoteType\": 1,\n              \"NamePos\": 32,\n              \"NameEnd\": 43\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 43,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": {\n      \"SelectPos\": 59,\n      \"StatementEnd\": 121,\n      \"With\": null,\n      \"Top\": null,\n      \"HasDistinct\": false,\n      \"DistinctOn\": null,\n      \"SelectItems\": [\n        {\n          \"Expr\": {\n            \"Name\": \"replica_name\",\n            \"QuoteType\": 1,\n            \"NamePos\": 66,\n            \"NameEnd\": 78\n          },\n          \"Modifiers\": [],\n          \"Alias\": null\n        }\n      ],\n      \"From\": {\n        \"FromPos\": 79,\n        \"Expr\": {\n          \"Table\": {\n            \"TablePos\": 84,\n            \"TableEnd\": 109,\n            \"Alias\": null,\n            \"Expr\": {\n              \"Database\": {\n                \"Name\": \"system\",\n                \"QuoteType\": 1,\n                \"NamePos\": 84,\n                \"NameEnd\": 90\n              },\n              \"Table\": {\n                \"Name\": \"ha_unique_replicas\",\n                \"QuoteType\": 1,\n                \"NamePos\": 91,\n                \"NameEnd\": 109\n              }\n            },\n            \"HasFinal\": false\n          },\n          \"StatementEnd\": 109,\n          \"SampleRatio\": null,\n          \"HasFinal\": false\n        }\n      },\n      \"Window\": null,\n      \"Prewhere\": null,\n      \"Where\": null,\n      \"GroupBy\": null,\n      \"WithTotal\": false,\n      \"Having\": null,\n      \"OrderBy\": null,\n      \"LimitBy\": null,\n      \"Limit\": null,\n      \"Settings\": null,\n      \"Format\": {\n        \"FormatPos\": 110,\n        \"Format\": {\n          \"Name\": \"JSON\",\n          \"QuoteType\": 1,\n          \"NamePos\": 117,\n          \"NameEnd\": 121\n        }\n      },\n      \"UnionAll\": null,\n      \"UnionDistinct\": null,\n      \"Except\": null\n    },\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_variable.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 47,\n    \"With\": {\n      \"WithPos\": 0,\n      \"EndPos\": 9,\n      \"CTEs\": [\n        {\n          \"CTEPos\": 5,\n          \"Expr\": {\n            \"Name\": \"$abc\",\n            \"QuoteType\": 1,\n            \"NamePos\": 5,\n            \"NameEnd\": 9\n          },\n          \"Alias\": {\n            \"SelectPos\": 14,\n            \"StatementEnd\": 27,\n            \"With\": null,\n            \"Top\": null,\n            \"HasDistinct\": false,\n            \"DistinctOn\": null,\n            \"SelectItems\": [\n              {\n                \"Expr\": {\n                  \"NumPos\": 21,\n                  \"NumEnd\": 22,\n                  \"Literal\": \"1\",\n                  \"Base\": 10\n                },\n                \"Modifiers\": [],\n                \"Alias\": {\n                  \"Name\": \"a\",\n                  \"QuoteType\": 1,\n                  \"NamePos\": 26,\n                  \"NameEnd\": 27\n                }\n              }\n            ],\n            \"From\": null,\n            \"Window\": null,\n            \"Prewhere\": null,\n            \"Where\": null,\n            \"GroupBy\": null,\n            \"WithTotal\": false,\n            \"Having\": null,\n            \"OrderBy\": null,\n            \"LimitBy\": null,\n            \"Limit\": null,\n            \"Settings\": null,\n            \"Format\": null,\n            \"UnionAll\": null,\n            \"UnionDistinct\": null,\n            \"Except\": null\n          }\n        }\n      ]\n    },\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"*\",\n          \"QuoteType\": 0,\n          \"NamePos\": 36,\n          \"NameEnd\": 36\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 38,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 43,\n          \"TableEnd\": 47,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"$abc\",\n              \"QuoteType\": 1,\n              \"NamePos\": 43,\n              \"NameEnd\": 47\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 47,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_with_window_function.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 508,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"Name\": \"aggregation_target\",\n          \"QuoteType\": 1,\n          \"NamePos\": 7,\n          \"NameEnd\": 25\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"aggregation_target\",\n          \"QuoteType\": 1,\n          \"NamePos\": 29,\n          \"NameEnd\": 47\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"timestamp\",\n          \"QuoteType\": 1,\n          \"NamePos\": 53,\n          \"NameEnd\": 62\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"timestamp\",\n          \"QuoteType\": 1,\n          \"NamePos\": 66,\n          \"NameEnd\": 75\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"step_0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 81,\n          \"NameEnd\": 87\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"step_0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 91,\n          \"NameEnd\": 97\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"latest_0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 103,\n          \"NameEnd\": 111\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"latest_0\",\n          \"QuoteType\": 1,\n          \"NamePos\": 115,\n          \"NameEnd\": 123\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"step_1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 129,\n          \"NameEnd\": 135\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"step_1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 139,\n          \"NameEnd\": 145\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"latest_1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 151,\n          \"NameEnd\": 159\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"latest_1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 163,\n          \"NameEnd\": 171\n        }\n      },\n      {\n        \"Expr\": {\n          \"Name\": \"step_2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 177,\n          \"NameEnd\": 183\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"step_2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 187,\n          \"NameEnd\": 193\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"min\",\n              \"QuoteType\": 1,\n              \"NamePos\": 199,\n              \"NameEnd\": 202\n            },\n            \"Params\": {\n              \"LeftParenPos\": 202,\n              \"RightParenPos\": 211,\n              \"Items\": {\n                \"ListPos\": 203,\n                \"ListEnd\": 211,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"latest_2\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 203,\n                      \"NameEnd\": 211\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 213,\n          \"OverExpr\": {\n            \"LeftParenPos\": 218,\n            \"RightParenPos\": 327,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 218,\n              \"Expr\": {\n                \"ListPos\": 232,\n                \"ListEnd\": 250,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"aggregation_target\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 232,\n                      \"NameEnd\": 250\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 255,\n              \"ListEnd\": 273,\n              \"Items\": [\n                {\n                  \"OrderPos\": 255,\n                  \"Expr\": {\n                    \"Name\": \"timestamp\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 264,\n                    \"NameEnd\": 273\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"DESC\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 279,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 292,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 312,\n                \"And\": {\n                  \"Number\": {\n                    \"NumPos\": 316,\n                    \"NumEnd\": 317,\n                    \"Literal\": \"0\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 327,\n                  \"Direction\": \"PRECEDING\"\n                }\n              }\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"latest_2\",\n          \"QuoteType\": 1,\n          \"NamePos\": 332,\n          \"NameEnd\": 340\n        }\n      },\n      {\n        \"Expr\": {\n          \"Function\": {\n            \"Name\": {\n              \"Name\": \"min\",\n              \"QuoteType\": 1,\n              \"NamePos\": 346,\n              \"NameEnd\": 349\n            },\n            \"Params\": {\n              \"LeftParenPos\": 349,\n              \"RightParenPos\": 358,\n              \"Items\": {\n                \"ListPos\": 350,\n                \"ListEnd\": 358,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"latest_1\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 350,\n                      \"NameEnd\": 358\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              },\n              \"ColumnArgList\": null\n            }\n          },\n          \"OverPos\": 360,\n          \"OverExpr\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 365,\n            \"NameEnd\": 366\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": {\n          \"Name\": \"latest_1\",\n          \"QuoteType\": 1,\n          \"NamePos\": 370,\n          \"NameEnd\": 378\n        }\n      }\n    ],\n    \"From\": {\n      \"FromPos\": 379,\n      \"Expr\": {\n        \"Table\": {\n          \"TablePos\": 384,\n          \"TableEnd\": 386,\n          \"Alias\": null,\n          \"Expr\": {\n            \"Database\": null,\n            \"Table\": {\n              \"Name\": \"t0\",\n              \"QuoteType\": 1,\n              \"NamePos\": 384,\n              \"NameEnd\": 386\n            }\n          },\n          \"HasFinal\": false\n        },\n        \"StatementEnd\": 386,\n        \"SampleRatio\": null,\n        \"HasFinal\": false\n      }\n    },\n    \"Window\": {\n      \"WindowPos\": 387,\n      \"EndPos\": 508,\n      \"Windows\": [\n        {\n          \"Name\": {\n            \"Name\": \"w\",\n            \"QuoteType\": 1,\n            \"NamePos\": 394,\n            \"NameEnd\": 395\n          },\n          \"AsPos\": 396,\n          \"Expr\": {\n            \"LeftParenPos\": 399,\n            \"RightParenPos\": 508,\n            \"WindowName\": null,\n            \"PartitionBy\": {\n              \"PartitionPos\": 399,\n              \"Expr\": {\n                \"ListPos\": 413,\n                \"ListEnd\": 431,\n                \"HasDistinct\": false,\n                \"Items\": [\n                  {\n                    \"Expr\": {\n                      \"Name\": \"aggregation_target\",\n                      \"QuoteType\": 1,\n                      \"NamePos\": 413,\n                      \"NameEnd\": 431\n                    },\n                    \"Alias\": null\n                  }\n                ]\n              }\n            },\n            \"OrderBy\": {\n              \"OrderPos\": 436,\n              \"ListEnd\": 454,\n              \"Items\": [\n                {\n                  \"OrderPos\": 436,\n                  \"Expr\": {\n                    \"Name\": \"timestamp\",\n                    \"QuoteType\": 1,\n                    \"NamePos\": 445,\n                    \"NameEnd\": 454\n                  },\n                  \"Alias\": null,\n                  \"Direction\": \"DESC\",\n                  \"Fill\": null\n                }\n              ],\n              \"Interpolate\": null\n            },\n            \"Frame\": {\n              \"FramePos\": 460,\n              \"Type\": \"ROWS\",\n              \"Extend\": {\n                \"Expr\": null,\n                \"Between\": {\n                  \"UnboundedPos\": 473,\n                  \"UnboundedEnd\": 0,\n                  \"Direction\": \"PRECEDING\"\n                },\n                \"AndPos\": 493,\n                \"And\": {\n                  \"Number\": {\n                    \"NumPos\": 497,\n                    \"NumEnd\": 498,\n                    \"Literal\": \"0\",\n                    \"Base\": 10\n                  },\n                  \"EndPos\": 508,\n                  \"Direction\": \"PRECEDING\"\n                }\n              }\n            }\n          }\n        }\n      ]\n    },\n    \"Prewhere\": null,\n    \"Where\": null,\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/select_without_from_where.sql.golden.json",
    "content": "[\n  {\n    \"SelectPos\": 0,\n    \"StatementEnd\": 20,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"NumPos\": 7,\n          \"NumEnd\": 8,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 9,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"NumPos\": 15,\n          \"NumEnd\": 16,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"Operation\": \"=\",\n        \"RightExpr\": {\n          \"NumPos\": 19,\n          \"NumEnd\": 20,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  },\n  {\n    \"SelectPos\": 22,\n    \"StatementEnd\": 60,\n    \"With\": null,\n    \"Top\": null,\n    \"HasDistinct\": false,\n    \"DistinctOn\": null,\n    \"SelectItems\": [\n      {\n        \"Expr\": {\n          \"LBracePos\": 29,\n          \"RBracePos\": 38,\n          \"Name\": {\n            \"Name\": \"p\",\n            \"QuoteType\": 1,\n            \"NamePos\": 30,\n            \"NameEnd\": 31\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 33,\n              \"NameEnd\": 38\n            }\n          }\n        },\n        \"Modifiers\": [],\n        \"Alias\": null\n      }\n    ],\n    \"From\": null,\n    \"Window\": null,\n    \"Prewhere\": null,\n    \"Where\": {\n      \"WherePos\": 40,\n      \"Expr\": {\n        \"LeftExpr\": {\n          \"LBracePos\": 46,\n          \"RBracePos\": 55,\n          \"Name\": {\n            \"Name\": \"p\",\n            \"QuoteType\": 1,\n            \"NamePos\": 47,\n            \"NameEnd\": 48\n          },\n          \"Type\": {\n            \"Name\": {\n              \"Name\": \"UInt8\",\n              \"QuoteType\": 1,\n              \"NamePos\": 50,\n              \"NameEnd\": 55\n            }\n          }\n        },\n        \"Operation\": \"=\",\n        \"RightExpr\": {\n          \"NumPos\": 59,\n          \"NumEnd\": 60,\n          \"Literal\": \"1\",\n          \"Base\": 10\n        },\n        \"HasGlobal\": false,\n        \"HasNot\": false\n      }\n    },\n    \"GroupBy\": null,\n    \"WithTotal\": false,\n    \"Having\": null,\n    \"OrderBy\": null,\n    \"LimitBy\": null,\n    \"Limit\": null,\n    \"Settings\": null,\n    \"Format\": null,\n    \"UnionAll\": null,\n    \"UnionDistinct\": null,\n    \"Except\": null\n  }\n]"
  },
  {
    "path": "parser/testdata/query/output/set_simple.sql.golden.json",
    "content": "[\n  {\n    \"SetPos\": 0,\n    \"Settings\": {\n      \"SettingsPos\": 4,\n      \"ListEnd\": 140,\n      \"Items\": [\n        {\n          \"SettingsPos\": 4,\n          \"Name\": {\n            \"Name\": \"max_threads\",\n            \"QuoteType\": 1,\n            \"NamePos\": 4,\n            \"NameEnd\": 15\n          },\n          \"Expr\": {\n            \"NumPos\": 18,\n            \"NumEnd\": 19,\n            \"Literal\": \"1\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 21,\n          \"Name\": {\n            \"Name\": \"max_insert_threads\",\n            \"QuoteType\": 1,\n            \"NamePos\": 21,\n            \"NameEnd\": 39\n          },\n          \"Expr\": {\n            \"NumPos\": 42,\n            \"NumEnd\": 43,\n            \"Literal\": \"0\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 45,\n          \"Name\": {\n            \"Name\": \"max_block_size\",\n            \"QuoteType\": 1,\n            \"NamePos\": 45,\n            \"NameEnd\": 59\n          },\n          \"Expr\": {\n            \"NumPos\": 62,\n            \"NumEnd\": 66,\n            \"Literal\": \"8192\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 68,\n          \"Name\": {\n            \"Name\": \"min_insert_block_size_rows\",\n            \"QuoteType\": 1,\n            \"NamePos\": 68,\n            \"NameEnd\": 94\n          },\n          \"Expr\": {\n            \"NumPos\": 97,\n            \"NumEnd\": 101,\n            \"Literal\": \"8192\",\n            \"Base\": 10\n          }\n        },\n        {\n          \"SettingsPos\": 103,\n          \"Name\": {\n            \"Name\": \"min_insert_block_size_bytes\",\n            \"QuoteType\": 1,\n            \"NamePos\": 103,\n            \"NameEnd\": 130\n          },\n          \"Expr\": {\n            \"NumPos\": 133,\n            \"NumEnd\": 140,\n            \"Literal\": \"1048576\",\n            \"Base\": 10\n          }\n        }\n      ]\n    }\n  }\n]"
  },
  {
    "path": "parser/testdata/query/query_with_expr_compare.sql",
    "content": "SELECT date, path, splitByChar('/', path)[2] AS path_b\nFROM(\n    SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date\n    )\nWHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30'\n  AND splitByChar('/', path)[1] = 'pathA'"
  },
  {
    "path": "parser/testdata/query/select_case_multiple_when.sql",
    "content": "SELECT\n    *,\n    CASE\n        WHEN col2 = 'value1' THEN 'when1'\n        WHEN col3 = 'value2' THEN 'when2'\n        ELSE 'else'\n    END as check_result\nFROM table_name\nWHERE col1 = '123456789'\n"
  },
  {
    "path": "parser/testdata/query/select_case_when_exists.sql",
    "content": "SELECT\n    *,\n    CASE\n        WHEN EXISTS(SELECT 1\n    FROM table_name\n    WHERE col1 = '999999999')\n        THEN 'then'\n        ELSE 'else'\n    END as check_result\nFROM table_name\nWHERE col1 = '123456789'\n"
  },
  {
    "path": "parser/testdata/query/select_cast.sql",
    "content": "select cast(1 as Float64) as value;\nselect cast(1, 'Float64') as value;\nselect (1 as Float64) as value;\nselect 1::Float64 as value;"
  },
  {
    "path": "parser/testdata/query/select_column_alias_string.sql",
    "content": "SELECT 'abc' as \"value2\";\n\nSELECT $abc, a$$bc, abc$$;\n"
  },
  {
    "path": "parser/testdata/query/select_concat_expr.sql",
    "content": "SELECT 'a' || 'b';\nSELECT 'a' || 'b' || 'c';\nSELECT 'a' || 'b' || 'c' + 5;\n"
  },
  {
    "path": "parser/testdata/query/select_expr.sql",
    "content": "SELECT 1+1"
  },
  {
    "path": "parser/testdata/query/select_extract_with_regex.sql",
    "content": "SELECT\n  COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT\nFROM\n  test.table\nWHERE\n  app_id = 999118646\n  AND toUnixTimestamp(timestamp) >= 1740366695\n  AND toUnixTimestamp(timestamp) <= 1740377495\nGROUP BY\n  CASE\n    WHEN length(extract(instance, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN instance\n    ELSE '空'\n  END,\n  CASE\n    WHEN length(extract(client_ip, '((\\\\d+\\\\.){3}\\\\d+)')) > 0 THEN client_ip\n    ELSE '空'\n  END,\n  src_type,\n  node_class,\n  port,\n  client_port\nLIMIT 10000\n"
  },
  {
    "path": "parser/testdata/query/select_item_with_modifiers.sql",
    "content": "SELECT c0 REPLACE(c0 AS c1) FROM t0;\nSELECT * REPLACE(i + 1 AS i) FROM t1;\nSELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from t2;\n"
  },
  {
    "path": "parser/testdata/query/select_json_type.sql",
    "content": "SELECT a, a.b, a.b.c.d.e;\nSELECT JSON_TYPE('{\"a\": 1, \"b\": {\"c\": 2}}', '$.b');\nSELECT CAST(some, 'String') AS value;\nSELECT CAST(some.long, 'String') AS value;\nSELECT CAST(some.long.json, 'String') AS value;\nSELECT CAST(some.long.json.path, 'String') AS value;\n\n"
  },
  {
    "path": "parser/testdata/query/select_keyword_alias_no_as.sql",
    "content": "SELECT 'Joe' name FROM users"
  },
  {
    "path": "parser/testdata/query/select_order_by_timestamp.sql",
    "content": "SELECT Timestamp FROM events ORDER BY Timestamp;"
  },
  {
    "path": "parser/testdata/query/select_order_by_with_fill_basic.sql",
    "content": "SELECT n, source FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL;\n"
  },
  {
    "path": "parser/testdata/query/select_order_by_with_fill_from_to.sql",
    "content": "SELECT n, source FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;\n"
  },
  {
    "path": "parser/testdata/query/select_order_by_with_fill_interpolate.sql",
    "content": "SELECT n, source, inter FROM (\n   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5\nINTERPOLATE (inter AS inter + 1);\n"
  },
  {
    "path": "parser/testdata/query/select_order_by_with_fill_interpolate_no_columns.sql",
    "content": "SELECT n, value FROM (\n   SELECT toFloat32(number % 10) AS n, number AS value\n   FROM numbers(10) WHERE number % 3 = 1\n) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1\nINTERPOLATE;\n"
  },
  {
    "path": "parser/testdata/query/select_order_by_with_fill_staleness.sql",
    "content": "SELECT number as key, 5 * number value, 'original' AS source\nFROM numbers(16)\nWHERE (number % 5) == 0\nORDER BY key WITH FILL STALENESS 11;\n"
  },
  {
    "path": "parser/testdata/query/select_order_by_with_fill_step.sql",
    "content": "SELECT date, value FROM (\n    SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value\n    FROM numbers(5)\n) ORDER BY date WITH FILL STEP INTERVAL 1 DAY;\n"
  },
  {
    "path": "parser/testdata/query/select_simple.sql",
    "content": "SELECT\n    f0, coalesce(f1, f2) AS f3, row_number()\nOVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2')\nAND f3 NOT IN ('a', 'b', 'c')\n\n\nGROUP BY f0,   f1\n\nLimit 100, 10 By f0;"
  },
  {
    "path": "parser/testdata/query/select_simple_field_alias.sql",
    "content": "SELECT field0, field1 as x, field2 y from events;"
  },
  {
    "path": "parser/testdata/query/select_simple_with_bracket.sql",
    "content": "SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1[\"abc\"] as f2\n"
  },
  {
    "path": "parser/testdata/query/select_simple_with_cte_with_column_aliases.sql",
    "content": "WITH\n    test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales)\nSELECT\n    f1 AS new_f1,\n    f2 AS new_f2,\n    f3 AS new_f3\nFROM\n    test;\n"
  },
  {
    "path": "parser/testdata/query/select_simple_with_group_by_with_cube_totals.sql",
    "content": "SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;"
  },
  {
    "path": "parser/testdata/query/select_simple_with_is_not_null.sql",
    "content": "SELECT f0,f1,f2,f3 as a0\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test'))\n  AND (f1 = 'testing')\n  AND f2 IS NULL\n  AND f3 IS NOT NULL"
  },
  {
    "path": "parser/testdata/query/select_simple_with_is_null.sql",
    "content": "SELECT f0,f1,f2,f3 as a0\nFROM test.events_local\nWHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL"
  },
  {
    "path": "parser/testdata/query/select_simple_with_limit.sql",
    "content": "SELECT 1 LIMIT 1;\nSELECT 1 LIMIT 1 OFFSET 0;\nSELECT 1 OFFSET 0;\n"
  },
  {
    "path": "parser/testdata/query/select_simple_with_top_clause.sql",
    "content": "SELECT TOP 10 my_column FROM tableName;\n"
  },
  {
    "path": "parser/testdata/query/select_simple_with_with_clause.sql",
    "content": "WITH\n    cte1 AS (SELECT f1 FROM t1),\n    cte2 AS (SELECT f2 FROM t2)\nSELECT\n    cte1.f1,\n    cte2.f2,\n    t3.f3\nFROM\n    t3,cte1,cte2\n\n"
  },
  {
    "path": "parser/testdata/query/select_table_alias_without_keyword.sql",
    "content": "SELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b"
  },
  {
    "path": "parser/testdata/query/select_table_function_with_query.sql",
    "content": "SELECT 1, (SELECT 70) AS `power`, number\nFROM\nnumbers(\n    plus(\n        ifNull((SELECT 1 AS bin_count, 1),\n        1)\n    )\n)"
  },
  {
    "path": "parser/testdata/query/select_when_condition.sql",
    "content": "select case when false then 'hello' else 'world' end;"
  },
  {
    "path": "parser/testdata/query/select_window_comprehensive.sql",
    "content": "-- Comprehensive window spec coverage: ad-hoc specs, named windows, ROWS/RANGE frames\n-- multiple functions, multi-column PARTITION/ORDER, and expression-based specs.\nSELECT\n    -- Ad-hoc windows\n    sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)                                         AS running_total,\n    avg(x)\n        OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)                                    AS avg_range1,\n\n    -- Named window reuse (OVER w1)\n    row_number() OVER w1                                                                                              AS rn_w1,\n    rank() OVER w1                                                                                                    AS rank_w1,\n    sum(x) OVER w1                                                                                                    AS sum_w1,\n\n    -- Frame variants (incl. shorthand & RANGE)\n    sum(x) OVER (ROWS 10 PRECEDING)                                                                                   AS rows_10_preceding,\n    sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)                                                    AS rows_cur_to_unbounded_following,\n    sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING)                                                            AS rows_5p_3f,\n    sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW)                                                          AS range_10p_cur,\n    sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)                                                   AS range_unbounded_to_cur,\n\n    -- Ranking & navigation\n    row_number() OVER (PARTITION BY y ORDER BY x)                                                                     AS row_num,\n    rank() OVER (PARTITION BY y ORDER BY x)                                                                           AS rank_val,\n    dense_rank() OVER (PARTITION BY y ORDER BY x)                                                                     AS dense_rank_val,\n    first_value(x)\n                OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)             AS first_val,\n    last_value(x)\n               OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)              AS last_val,\n    lag(x, 1) OVER (PARTITION BY y ORDER BY x)                                                                        AS prev_x,\n    lead(x, 1) OVER (PARTITION BY y ORDER BY x)                                                                       AS next_x,\n    percent_rank() OVER (PARTITION BY y ORDER BY x)                                                                   AS pct_rank,\n\n    -- Named window reference via OVER w (no parentheses)\n    sum(x) OVER w                                                                                                     AS sum_over_w,\n    avg(x) OVER w                                                                                                     AS avg_over_w,\n    row_number() OVER w                                                                                               AS rn_over_w,\n\n    -- Multiple columns in PARTITION BY / ORDER BY\n    count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC)                                            AS cnt_multi,\n    sum(val)\n        OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)           AS total_multi,\n\n    -- Expressions in PARTITION/ORDER\n    sum(amount)\n        OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total,\n    avg(amount)\n        OVER (ORDER BY extract(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)                        AS hourly_avg\nFROM t\nWINDOW w AS (ORDER BY y),\n       w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),\n       w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW),\n       w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n"
  },
  {
    "path": "parser/testdata/query/select_window_cte.sql",
    "content": "WITH\n    monthly AS (\n        SELECT toStartOfMonth(date) AS month,\n               department,\n               avg(salary)          AS avg_salary\n        FROM salary_table\n        WHERE year = 2023\n        GROUP BY month, department\n    ),\n    ranked AS (\n        SELECT month,\n               department,\n               avg_salary,\n               row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank\n        FROM monthly\n    )\nSELECT month,\n       department,\n       avg_salary,\n       lag(avg_salary, 1, 0) OVER (\n           PARTITION BY department\n           ORDER BY month\n           ROWS BETWEEN 1 PRECEDING AND CURRENT ROW\n           ) AS prev_month_avg\nFROM ranked\nWHERE dept_rank <= 5\nORDER BY month, department;\n"
  },
  {
    "path": "parser/testdata/query/select_window_keyword_name_in_parens.sql",
    "content": "SELECT sum(x) OVER (order) AS sum_over_order\nFROM t\nWINDOW order AS (PARTITION BY team ORDER BY ts);\n"
  },
  {
    "path": "parser/testdata/query/select_window_named_in_parens.sql",
    "content": "SELECT sum(x) OVER (w) AS sum_over_w\nFROM t\nWINDOW w AS (PARTITION BY y ORDER BY x);\n"
  },
  {
    "path": "parser/testdata/query/select_window_named_reference_extensions.sql",
    "content": "SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,\n       avg(x) OVER (w2)                                                      AS avg_over_w2\nFROM t\nWINDOW w1 AS (PARTITION BY team),\n       w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);\n"
  },
  {
    "path": "parser/testdata/query/select_window_params.sql",
    "content": "-- Parameters in WHERE and in window frames (UInt32 & String; both spacing styles; shorthand frame)\nSELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start:UInt32} PRECEDING AND CURRENT ROW)                           AS total1,\n       avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end:UInt32} FOLLOWING)                             AS avg1,\n       count(*) OVER (ORDER BY y RANGE BETWEEN {range_start:UInt32} PRECEDING AND {range_end:UInt32} FOLLOWING) AS cnt1,\n       sum(x) OVER (ROWS {window_size :UInt32} PRECEDING)                                                       AS rows_shorthand\nFROM t\nWHERE category = {category :String}\n  AND type = {type:String};\n"
  },
  {
    "path": "parser/testdata/query/select_with_distinct.sql",
    "content": "SELECT count(DISTINCT(RECORD_ID)) FROM RECORD_TABLE"
  },
  {
    "path": "parser/testdata/query/select_with_distinct_keyword.sql",
    "content": "SELECT DISTINCT record_id FROM records "
  },
  {
    "path": "parser/testdata/query/select_with_distinct_on_dotted_columns.sql",
    "content": "SELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table t"
  },
  {
    "path": "parser/testdata/query/select_with_distinct_on_keyword.sql",
    "content": "SELECT DISTINCT ON(album,artist) record_id FROM records"
  },
  {
    "path": "parser/testdata/query/select_with_group_by.sql",
    "content": "SELECT\n    datacenter,\n    distro,\n    SUM (quantity) AS qty\nFROM\n    servers\nGROUP BY\n    GROUPING SETS(\n    (datacenter,distro),\n    (datacenter),\n    (distro),\n    ()\n);\n\nSELECT\n    datacenter,\n    distro,\n    SUM (quantity) AS qty\nFROM\n    servers\nGROUP BY ALL;"
  },
  {
    "path": "parser/testdata/query/select_with_join_only.sql",
    "content": "SELECT * FROM \"t1\" JOIN \"t2\" ON true\n"
  },
  {
    "path": "parser/testdata/query/select_with_keyword_in_group_by.sql",
    "content": "SELECT\n    toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval,\n    column_name\nFROM table\nWHERE true\nGROUP BY (interval, column_name)\nORDER BY (interval AS i, column_name) ASC"
  },
  {
    "path": "parser/testdata/query/select_with_keyword_placeholder.sql",
    "content": "SELECT {name :String};\nSELECT toString({name :String});\n\n"
  },
  {
    "path": "parser/testdata/query/select_with_left_join.sql",
    "content": "WITH\n    t1 AS\n        (\n            SELECT 1 AS value\n    ),\n    t2 AS\n       (\nSELECT 2 AS value\n    )\nSELECT *\nFROM t1\n         LEFT JOIN t2 ON true"
  },
  {
    "path": "parser/testdata/query/select_with_literal_table_name.sql",
    "content": "select table_name from \"information_schema\".\"tables\" limit 1;\n"
  },
  {
    "path": "parser/testdata/query/select_with_multi_array_and_inner_join.sql",
    "content": "SELECT\n    JSONExtractString(t3.props, 'value') AS value\nFROM t1\n    ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1\n    INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id')\n    ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2\n    INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id')\nWHERE value != '';"
  },
  {
    "path": "parser/testdata/query/select_with_multi_array_join.sql",
    "content": "SELECT\n    v,\n    j\nFROM t1\n    ARRAY JOIN JSONExtractArrayRaw(a) AS j\n    ARRAY JOIN array(\n    JSONExtractString(j, 'x'),\n    JSONExtractString(j, 'y')\n) AS v;"
  },
  {
    "path": "parser/testdata/query/select_with_multi_except.sql",
    "content": "SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9)"
  },
  {
    "path": "parser/testdata/query/select_with_multi_join.sql",
    "content": "with t1 as (\n    select 'value1' as value\n    ), t2 as (\nselect 'value2' as value\n    ), t3 as (\nselect 'value3' as value\n    )\nselect\n    t1.value as value1,\n    t2.value as value2,\n    t3.value as value3\nfrom\n    t1\n        join t2 on true\n        join t3\n        join t4 on true\n        join t5\n"
  },
  {
    "path": "parser/testdata/query/select_with_multi_line_comment.sql",
    "content": "select\n    -- first line\n    -- second line\n    *\nfrom\n    t0"
  },
  {
    "path": "parser/testdata/query/select_with_multi_union.sql",
    "content": "SELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3\n"
  },
  {
    "path": "parser/testdata/query/select_with_multi_union_distinct.sql",
    "content": "SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3"
  },
  {
    "path": "parser/testdata/query/select_with_number_field.sql",
    "content": "SELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m as bar"
  },
  {
    "path": "parser/testdata/query/select_with_placeholder.sql",
    "content": "SELECT * FROM t0 WHERE id = ?;"
  },
  {
    "path": "parser/testdata/query/select_with_query_parameter.sql",
    "content": "SET param_a = 13;\nSET param_b = 'str';\nSET param_c = '2022-08-04 18:30:53';\nSET param_d = {'10': [11, 12], '13': [14, 15]};\n\nSELECT\n    {a: UInt32},\n    {b: String},\n    {c: DateTime},\n    {d: Map(String, Array(UInt8))};\n\nSELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String};\n"
  },
  {
    "path": "parser/testdata/query/select_with_settings_additional_table_filters.sql",
    "content": "SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'};\n\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \\'test\\''};\n\nSELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''};\n\nSELECT * FROM test_table\nSETTINGS additional_table_filters={'test_table': 'id IN (\\'a\\', \\'b\\') AND status = \\'active\\''}\nFORMAT JSON;\n\nSELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) f\nANY LEFT JOIN (SELECT x, y FROM table_1) s ON f.number = s.x\nSETTINGS additional_table_filters={'system.numbers':'number != 3', 'table_1':'x != 2'};\n"
  },
  {
    "path": "parser/testdata/query/select_with_single_quote_table.sql",
    "content": "SELECT * FROM 'test_table'\n"
  },
  {
    "path": "parser/testdata/query/select_with_string_expr.sql",
    "content": "WITH \"abc\" AS (SELECT 1 AS a) SELECT * FROM \"abc\"\n"
  },
  {
    "path": "parser/testdata/query/select_with_union_distinct.sql",
    "content": "SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON"
  },
  {
    "path": "parser/testdata/query/select_with_variable.sql",
    "content": "WITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc"
  },
  {
    "path": "parser/testdata/query/select_with_window_function.sql",
    "content": "SELECT aggregation_target AS aggregation_target,\n    timestamp AS timestamp,\n    step_0 AS step_0,\n    latest_0 AS latest_0,\n    step_1 AS step_1,\n    latest_1 AS latest_1,\n    step_2 AS step_2,\n    min(latest_2) OVER (PARTITION BY aggregation_target\n    ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2,\n    min(latest_1) OVER w AS latest_1\nFROM t0\nWINDOW w AS (PARTITION BY aggregation_target\n    ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING);"
  },
  {
    "path": "parser/testdata/query/select_without_from_where.sql",
    "content": "SELECT 1 WHERE 1 = 1;\nSELECT {p :UInt8} WHERE {p :UInt8} = 1;\n\n"
  },
  {
    "path": "parser/testdata/query/set_simple.sql",
    "content": "SET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage"
  },
  {
    "path": "parser/type.go",
    "content": "package parser\n\nvar intervalUnits = NewSet(\"MILLISECOND\", \"SECOND\", \"MINUTE\", \"HOUR\", \"DAY\", \"WEEK\", \"MONTH\", \"QUARTER\", \"YEAR\")\n"
  },
  {
    "path": "parser/visitor_test.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/sebdah/goldie/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestVisitor_Identical(t *testing.T) {\n\tfor _, dir := range []string{\"./testdata/dml\", \"./testdata/ddl\", \"./testdata/query\", \"./testdata/basic\"} {\n\t\toutputDir := dir + \"/format\"\n\n\t\tentries, err := os.ReadDir(dir)\n\t\trequire.NoError(t, err)\n\t\tfor _, entry := range entries {\n\t\t\tif !strings.HasSuffix(entry.Name(), \".sql\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.Run(entry.Name(), func(t *testing.T) {\n\t\t\t\tfileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name()))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tparser := Parser{\n\t\t\t\t\tlexer: NewLexer(string(fileBytes)),\n\t\t\t\t}\n\t\t\t\tstmts, err := parser.ParseStmts()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tvar builder strings.Builder\n\t\t\t\tbuilder.WriteString(\"-- Origin SQL:\\n\")\n\t\t\t\tbuilder.Write(fileBytes)\n\t\t\t\tbuilder.WriteString(\"\\n\\n-- Format SQL:\\n\")\n\t\t\t\tvar formatSQLBuilder strings.Builder\n\t\t\t\tfor _, stmt := range stmts {\n\t\t\t\t\t// Use Walk to traverse the AST (equivalent to the visitor doing nothing)\n\t\t\t\t\tWalk(stmt, func(node Expr) bool {\n\t\t\t\t\t\treturn true // Continue traversal\n\t\t\t\t\t})\n\n\t\t\t\t\tformatSQLBuilder.WriteString(Format(stmt))\n\t\t\t\t\tformatSQLBuilder.WriteByte(';')\n\t\t\t\t\tformatSQLBuilder.WriteByte('\\n')\n\t\t\t\t}\n\t\t\t\tformatSQL := formatSQLBuilder.String()\n\t\t\t\tbuilder.WriteString(formatSQL)\n\t\t\t\tvalidFormatSQL(t, formatSQL)\n\t\t\t\tg := goldie.New(t,\n\t\t\t\t\tgoldie.WithNameSuffix(\"\"),\n\t\t\t\t\tgoldie.WithDiffEngine(goldie.ColoredDiff),\n\t\t\t\t\tgoldie.WithFixtureDir(outputDir))\n\t\t\t\tg.Assert(t, entry.Name(), []byte(builder.String()))\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc TestVisitor_SimpleRewrite(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, 1, len(stmts))\n\tstmt := stmts[0]\n\n\t// Rewrite using Walk function\n\tWalk(stmt, func(node Expr) bool {\n\t\tswitch expr := node.(type) {\n\t\tcase *TableIdentifier:\n\t\t\tif Format(expr.Table) == \"group_by_all\" {\n\t\t\t\texpr.Table = &Ident{Name: \"hack\"}\n\t\t\t}\n\t\tcase *OrderExpr:\n\t\t\texpr.Direction = OrderDirectionDesc\n\t\t}\n\t\treturn true // Continue traversal\n\t})\n\n\tnewSql := Format(stmt)\n\n\trequire.NotSame(t, sql, newSql)\n\trequire.True(t, strings.Contains(newSql, \"hack\"))\n\trequire.True(t, strings.Contains(newSql, string(OrderDirectionDesc)))\n}\n\nfunc TestVisitor_NestRewrite(t *testing.T) {\n\tsql := `SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, 1, len(stmts))\n\tstmt := stmts[0]\n\n\t// Track nesting depth with closure variables\n\tvar stack []Expr\n\n\tWalk(stmt, func(node Expr) bool {\n\t\t// Simulate Enter behavior\n\t\tif s, ok := node.(*SelectQuery); ok {\n\t\t\tstack = append(stack, s)\n\t\t}\n\n\t\t// Process TableIdentifier nodes\n\t\tif expr, ok := node.(*TableIdentifier); ok {\n\t\t\texpr.Table = &Ident{Name: fmt.Sprintf(\"table%d\", len(stack))}\n\t\t}\n\n\t\t// Continue with children\n\t\treturn true\n\t})\n\n\tnewSql := Format(stmt)\n\n\trequire.NotSame(t, sql, newSql)\n\t// Both table names should be rewritten (they might both be table1 since they're at the same depth)\n\trequire.True(t, strings.Contains(newSql, \"table1\") || strings.Contains(newSql, \"table2\"))\n}\n\n// TestWalk_NodeCounting verifies that Walk visits all nodes in the AST\nfunc TestWalk_NodeCounting(t *testing.T) {\n\tsql := `SELECT a FROM table1`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\n\tvar nodeCount int\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tnodeCount++\n\t\treturn true\n\t})\n\n\t// Verify that we visited multiple nodes\n\trequire.Greater(t, nodeCount, 0, \"Walk should visit nodes\")\n\trequire.Greater(t, nodeCount, 3, \"Should visit at least SELECT, column, table nodes\")\n}\n"
  },
  {
    "path": "parser/walk.go",
    "content": "package parser\n\nimport \"reflect\"\n\n// WalkFunc is a function type for walking AST nodes.\n// It receives the current node and returns a boolean indicating whether to continue walking.\n// If the function returns false, the walking stops for the current subtree.\ntype WalkFunc func(node Expr) bool\n\n// Walk traverses an AST in depth-first order, calling the provided function\n// for each node. If the function returns false, traversal stops for that subtree.\nfunc Walk(node Expr, fn WalkFunc) bool {\n\tif node == nil || reflect.ValueOf(node).IsNil() {\n\t\treturn true\n\t}\n\tif !fn(node) {\n\t\treturn false\n\t}\n\n\tswitch n := node.(type) {\n\tcase *SelectQuery:\n\t\tif !Walk(n.With, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.DistinctOn, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Top, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, item := range n.SelectItems {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.From, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Window, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Prewhere, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Where, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.GroupBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Having, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OrderBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.LimitBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Limit, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.UnionAll, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.UnionDistinct, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Format, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SubQuery:\n\t\tif !Walk(n.Select, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SelectItem:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, modifier := range n.Modifiers {\n\t\t\tif !Walk(modifier, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.Alias, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TableExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Alias, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AliasExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Alias, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *FunctionExpr:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Params, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TableIdentifier:\n\t\tif !Walk(n.Database, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *Ident:\n\t\t// Leaf node\n\tcase *NumberLiteral:\n\t\t// Leaf node\n\tcase *StringLiteral:\n\t\t// Leaf node\n\tcase *NullLiteral:\n\t\t// Leaf node\n\tcase *NotNullLiteral:\n\t\tif !Walk(n.NullLiteral, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ColumnExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Alias, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *BinaryOperation:\n\t\tif !Walk(n.LeftExpr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.RightExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *WhenClause:\n\t\tif !Walk(n.When, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Then, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CaseExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, when := range n.Whens {\n\t\t\tif !Walk(when, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.Else, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CastExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.AsType, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *Path:\n\t\tfor _, field := range n.Fields {\n\t\t\tif !Walk(field, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *WithClause:\n\t\tfor _, cte := range n.CTEs {\n\t\t\tif !Walk(cte, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *CTEStmt:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Alias, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *FromClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *JoinExpr:\n\t\tif !Walk(n.Left, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Right, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Constraints, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *JoinTableExpr:\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SampleRatio, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *OnClause:\n\t\tif !Walk(n.On, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *UsingClause:\n\t\tif !Walk(n.Using, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *WhereClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PrewhereClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *GroupByClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *HavingClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *OrderByClause:\n\t\tfor _, item := range n.Items {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.Interpolate, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *OrderExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Alias, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Fill, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *Fill:\n\t\tif !Walk(n.From, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.To, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Step, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Staleness, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *InterpolateClause:\n\t\tfor _, item := range n.Items {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *InterpolateItem:\n\t\tif !Walk(n.Column, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *LimitClause:\n\t\tif !Walk(n.Limit, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Offset, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *LimitByClause:\n\t\tif !Walk(n.Limit, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ByExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SettingsClause:\n\t\tfor _, item := range n.Items {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *SettingExpr:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *FormatClause:\n\t\tif !Walk(n.Format, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *InsertStmt:\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ColumnNames, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Format, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SelectExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ColumnNamesExpr:\n\t\tfor i := range n.ColumnNames {\n\t\t\tif !Walk(&n.ColumnNames[i], fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *AssignmentValues:\n\t\tfor _, value := range n.Values {\n\t\t\tif !Walk(value, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *TableFunctionExpr:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Args, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TableArgListExpr:\n\t\tfor _, arg := range n.Args {\n\t\t\tif !Walk(arg, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *NestedIdentifier:\n\t\tif !Walk(n.Ident, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.DotIdent, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ArrayParamList:\n\t\tif !Walk(n.Items, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ColumnExprList:\n\t\tfor _, item := range n.Items {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *ParamExprList:\n\t\tif !Walk(n.Items, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ColumnArgList, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ColumnArgList:\n\t\tfor _, item := range n.Items {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *WindowClause:\n\t\tfor _, window := range n.Windows {\n\t\t\tif window == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !Walk(window.Name, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !Walk(window.Expr, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *WindowExpr:\n\t\tif !Walk(n.WindowName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.PartitionBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OrderBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Frame, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PartitionByClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *WindowFrameClause:\n\t\tif !Walk(n.Extend, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *WindowFrameExtendExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *BetweenClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Between, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.And, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *WindowFrameCurrentRow:\n\t\t// Leaf node\n\tcase *WindowFrameUnbounded:\n\t\t// Leaf node\n\tcase *WindowFrameNumber:\n\t\tif !Walk(n.Number, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TopClause:\n\t\tif !Walk(n.Number, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SampleClause:\n\t\tif !Walk(n.Ratio, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Offset, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *RatioExpr:\n\t\tif !Walk(n.Numerator, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Denominator, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *IntervalExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Unit, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DropStmt:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DropDatabase:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DropUserOrRole:\n\t\tfor _, name := range n.Names {\n\t\t\tif !Walk(name, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.From, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TruncateTable:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CheckStmt:\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *OptimizeStmt:\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Deduplicate, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DeduplicateClause:\n\t\tif !Walk(n.By, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Except, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SystemStmt:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SystemFlushExpr:\n\t\tif !Walk(n.Distributed, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SystemReloadExpr:\n\t\tif !Walk(n.Dictionary, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SystemSyncExpr:\n\t\tif !Walk(n.Cluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SystemCtrlExpr:\n\t\tif !Walk(n.Cluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SystemDropExpr:\n\t\t// Leaf node\n\tcase *UseStmt:\n\t\tif !Walk(n.Database, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SetStmt:\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ExplainStmt:\n\t\tif !Walk(n.Statement, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *GrantPrivilegeStmt:\n\t\tfor _, privilege := range n.Privileges {\n\t\t\tif !Walk(privilege, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.On, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, role := range n.To {\n\t\t\tif !Walk(role, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PrivilegeClause:\n\t\tif !Walk(n.Params, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *RenameStmt:\n\t\tfor _, pair := range n.TargetPairList {\n\t\t\tif !Walk(pair.Old, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !Walk(pair.New, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DeleteClause:\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.WhereExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateDatabase:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Engine, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Comment, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateTable:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.UUID, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TableSchema, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Engine, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SubQuery, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TableFunction, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Comment, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateView:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.UUID, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TableSchema, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Comment, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SubQuery, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateMaterializedView:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Refresh, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.RandomizeFor, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, dep := range n.DependsOn {\n\t\t\tif !Walk(dep, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Engine, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Destination, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SubQuery, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Comment, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Definer, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateLiveView:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.UUID, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Destination, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TableSchema, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.WithTimeout, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SubQuery, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateDictionary:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.UUID, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Schema, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Engine, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Comment, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateFunction:\n\t\tif !Walk(n.FunctionName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Params, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *CreateRole:\n\t\tfor _, name := range n.RoleNames {\n\t\t\tif !Walk(name, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.AccessStorageType, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, setting := range n.Settings {\n\t\t\tif !Walk(setting, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *CreateUser:\n\t\tfor _, name := range n.UserNames {\n\t\t\tif !Walk(name, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.Authentication, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ValidUntil, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, host := range n.Hosts {\n\t\t\tif !Walk(host, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.DefaultRole, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.DefaultDatabase, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Grantees, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, setting := range n.Settings {\n\t\t\tif !Walk(setting, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *AlterTable:\n\t\tif !Walk(n.TableIdentifier, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, expr := range n.AlterExprs {\n\t\t\tif !Walk(expr, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *AlterTableAttachPartition:\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.From, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableDetachPartition:\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableDropPartition:\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableMaterializeProjection:\n\t\tif !Walk(n.ProjectionName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableMaterializeIndex:\n\t\tif !Walk(n.IndexName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableFreezePartition:\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableAddColumn:\n\t\tif !Walk(n.Column, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.After, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableAddIndex:\n\t\tif !Walk(n.Index, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.After, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableAddProjection:\n\t\tif !Walk(n.TableProjection, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.After, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableDropColumn:\n\t\tif !Walk(n.ColumnName, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableDropIndex:\n\t\tif !Walk(n.IndexName, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableDropProjection:\n\t\tif !Walk(n.ProjectionName, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableRemoveTTL:\n\t\t// Leaf node\n\tcase *AlterTableClearColumn:\n\t\tif !Walk(n.ColumnName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.PartitionExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableClearIndex:\n\t\tif !Walk(n.IndexName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.PartitionExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableClearProjection:\n\t\tif !Walk(n.ProjectionName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.PartitionExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableRenameColumn:\n\t\tif !Walk(n.OldColumnName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.NewColumnName, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableModifyQuery:\n\t\tif !Walk(n.SelectExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableModifyTTL:\n\t\tif !Walk(n.TTL, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableModifyColumn:\n\t\tif !Walk(n.Column, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.RemovePropertyType, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableModifySetting:\n\t\tfor _, setting := range n.Settings {\n\t\t\tif !Walk(setting, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *AlterTableResetSetting:\n\t\tfor _, setting := range n.Settings {\n\t\t\tif !Walk(setting, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *AlterTableReplacePartition:\n\t\tif !Walk(n.Partition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Table, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableDelete:\n\t\tif !Walk(n.WhereClause, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterTableUpdate:\n\t\tfor _, assignment := range n.Assignments {\n\t\t\tif !Walk(assignment, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.InPartition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.WhereClause, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *UpdateAssignment:\n\t\tif !Walk(n.Column, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AlterRole:\n\t\tfor _, pair := range n.RoleRenamePairs {\n\t\t\tif !Walk(pair, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tfor _, setting := range n.Settings {\n\t\t\tif !Walk(setting, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *RoleRenamePair:\n\t\tif !Walk(n.RoleName, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.NewName, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TableSchemaClause:\n\t\tfor _, column := range n.Columns {\n\t\t\tif !Walk(column, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.AliasTable, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TableFunction, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ColumnDef:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Type, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.NotNull, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Nullable, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.DefaultExpr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.MaterializedExpr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.AliasExpr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Codec, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TTL, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Comment, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ScalarType:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *JSONType:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PropertyType:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TypeWithParams:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, param := range n.Params {\n\t\t\tif !Walk(param, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *ComplexType:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, param := range n.Params {\n\t\t\tif !Walk(param, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *NestedType:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, column := range n.Columns {\n\t\t\tif !Walk(column, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *CompressionCodec:\n\t\tif !Walk(n.Type, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TypeLevel, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Level, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *EngineExpr:\n\t\tif !Walk(n.Params, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.PrimaryKey, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.PartitionBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SampleBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TTL, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OrderBy, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PrimaryKeyClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SampleByClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TTLClause:\n\t\tfor _, item := range n.Items {\n\t\t\tif !Walk(item, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *TTLExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Policy, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TTLPolicy:\n\t\tif !Walk(n.Item, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Where, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.GroupBy, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TTLPolicyRule:\n\t\tif !Walk(n.ToVolume, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ToDisk, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TTLPolicyRuleAction:\n\t\tif !Walk(n.Codec, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *RefreshExpr:\n\t\tif !Walk(n.Interval, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Offset, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DestinationClause:\n\t\tif !Walk(n.TableIdentifier, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TableSchema, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ConstraintClause:\n\t\tif !Walk(n.Constraint, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *RoleName:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Scope, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OnCluster, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *SettingPair:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Value, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *RoleSetting:\n\t\tfor _, pair := range n.SettingPairs {\n\t\t\tif !Walk(pair, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !Walk(n.Modifier, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *AuthenticationClause:\n\t\tif !Walk(n.AuthValue, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.LdapServer, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.KerberosRealm, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *HostClause:\n\t\tif !Walk(n.HostValue, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DefaultRoleClause:\n\t\tfor _, role := range n.Roles {\n\t\t\tif !Walk(role, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *GranteesClause:\n\t\tfor _, grantee := range n.Grantees {\n\t\t\tif !Walk(grantee, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tfor _, except := range n.ExceptUsers {\n\t\t\tif !Walk(except, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *WithTimeoutClause:\n\t\tif !Walk(n.Number, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DictionarySchemaClause:\n\t\tfor _, attr := range n.Attributes {\n\t\t\tif !Walk(attr, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *DictionaryAttribute:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Type, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Default, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Expression, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DictionaryEngineClause:\n\t\tif !Walk(n.PrimaryKey, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Source, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Lifetime, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Layout, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Range, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Settings, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DictionaryPrimaryKeyClause:\n\t\tif !Walk(n.Keys, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DictionarySourceClause:\n\t\tif !Walk(n.Source, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, arg := range n.Args {\n\t\t\tif !Walk(arg, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *DictionaryArgExpr:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Value, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DictionaryLifetimeClause:\n\t\tif !Walk(n.Value, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Min, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Max, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DictionaryLayoutClause:\n\t\tif !Walk(n.Layout, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, arg := range n.Args {\n\t\t\tif !Walk(arg, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *DictionaryRangeClause:\n\t\tif !Walk(n.Min, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Max, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PlaceHolder:\n\t\t// Leaf node\n\tcase *TypedPlaceholder:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Type, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *QueryParam:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Type, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *MapLiteral:\n\t\tfor _, kv := range n.KeyValues {\n\t\t\tif !Walk(&kv.Key, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !Walk(kv.Value, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *NamedParameterExpr:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Value, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ObjectParams:\n\t\tif !Walk(n.Object, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Params, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *WindowFunctionExpr:\n\t\tif !Walk(n.Function, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OverExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *NotExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *NegateExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *GlobalInOperation:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ExtractExpr:\n\t\tfor _, param := range n.Parameters {\n\t\t\tif !Walk(param, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *IntervalFrom:\n\t\tif !Walk(n.Interval, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.FromExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *IsNullExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *IsNotNullExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TernaryOperation:\n\t\tif !Walk(n.Condition, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.TrueExpr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.FalseExpr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *IndexOperation:\n\t\tif !Walk(n.Object, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Index, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *OperationExpr:\n\t\t// Leaf node\n\tcase *TableIndex:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ColumnExpr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ColumnType, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Granularity, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ProjectionOrderByClause:\n\t\tif !Walk(n.Columns, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ProjectionSelectStmt:\n\t\tif !Walk(n.With, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.SelectColumns, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.GroupBy, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OrderBy, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TableProjection:\n\t\tif !Walk(n.Identifier, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Select, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *RemovePropertyType:\n\t\tif !Walk(n.PropertyType, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *EnumType:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tfor i := range n.Values {\n\t\t\tif !Walk(&n.Values[i], fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase *EnumValue:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Value, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ClusterClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *PartitionClause:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.ID, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *UUID:\n\t\tif !Walk(n.Value, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ColumnTypeExpr:\n\t\tif !Walk(n.Name, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *UnaryExpr:\n\t\tif !Walk(n.Expr, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *JoinConstraintClause:\n\t\tif !Walk(n.On, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Using, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *TargetPair:\n\t\tif !Walk(n.Old, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.New, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *ShowStmt:\n\t\tif !Walk(n.Target, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.LikePattern, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Limit, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.OutFile, fn) {\n\t\t\treturn false\n\t\t}\n\t\tif !Walk(n.Format, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DescribeStmt:\n\t\tif !Walk(n.Target, fn) {\n\t\t\treturn false\n\t\t}\n\tcase *DistinctOn:\n\t\tfor _, ident := range n.Idents {\n\t\t\tif !Walk(ident, fn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// WalkWithBreak allows for early termination of tree traversal.\n// The provided function should return true to continue walking,\n// or false to stop the traversal entirely.\nfunc WalkWithBreak(node Expr, fn WalkFunc) bool {\n\tif node == nil {\n\t\treturn true\n\t}\n\n\t// Call the function first - if it returns false, stop immediately\n\tif !fn(node) {\n\t\treturn false\n\t}\n\n\t// For early termination support, use a helper that converts our function\n\t// to one that collects a boolean result\n\tvar continueWalk = true\n\tWalk(node, func(child Expr) bool {\n\t\t// Skip the current node since we already processed it\n\t\tif child == node {\n\t\t\treturn true\n\t\t}\n\t\t// Call our termination-aware function\n\t\tif !fn(child) {\n\t\t\tcontinueWalk = false\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t})\n\n\treturn continueWalk\n}\n\n// Find searches for the first node matching the given predicate.\n// Returns the matching node and true if found, or nil and false if not found.\nfunc Find(root Expr, predicate func(Expr) bool) (Expr, bool) {\n\tvar found Expr\n\tWalkWithBreak(root, func(node Expr) bool {\n\t\tif predicate(node) {\n\t\t\tfound = node\n\t\t\treturn false // Stop traversal\n\t\t}\n\t\treturn true // Continue traversal\n\t})\n\treturn found, found != nil\n}\n\n// FindAll collects all nodes matching the given predicate.\nfunc FindAll(root Expr, predicate func(Expr) bool) []Expr {\n\tvar matches []Expr\n\tWalk(root, func(node Expr) bool {\n\t\tif predicate(node) {\n\t\t\tmatches = append(matches, node)\n\t\t}\n\t\treturn true // Always continue traversal\n\t})\n\treturn matches\n}\n\n// Transform applies a transformation function to all nodes in the tree.\n// The transformation function receives a node and should return the transformed node.\n// Note: This modifies the tree in place for mutable fields.\nfunc Transform(root Expr, transformer func(Expr) Expr) Expr {\n\ttransformed := transformer(root)\n\tif transformed == nil {\n\t\treturn nil\n\t}\n\n\t// Apply transformations to children\n\tWalk(transformed, func(node Expr) bool {\n\t\t// The actual in-place transformation would need to be implemented\n\t\t// based on the specific needs and mutability of the AST nodes\n\t\treturn true\n\t})\n\n\treturn transformed\n}\n"
  },
  {
    "path": "parser/walk_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestWalk_BasicTraversal(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM table1 WHERE id > 10 ORDER BY a;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\tvar nodeCount int\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tnodeCount++\n\t\treturn true\n\t})\n\n\t// Verify we visited multiple nodes\n\trequire.Greater(t, nodeCount, 10, \"Should have visited more than 10 nodes\")\n}\n\nfunc TestWalk_JoinExpr(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM table1 JOIN table2 ON table1.id = table2.id;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\tvar onClauses int\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tif _, ok := node.(*OnClause); ok {\n\t\t\tonClauses++\n\t\t}\n\t\treturn true\n\t})\n\n\trequire.Equal(t, 1, onClauses, \"Should have visited exactly 1 OnClause\")\n}\n\nfunc TestWalkWithBreak_EarlyTermination(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM table1 WHERE id > 10 ORDER BY a;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\tvar nodeCount int\n\tresult := WalkWithBreak(stmts[0], func(node Expr) bool {\n\t\tnodeCount++\n\t\t// Stop after visiting 5 nodes\n\t\treturn nodeCount < 5\n\t})\n\n\trequire.False(t, result, \"WalkWithBreak should return false when terminated early\")\n\trequire.Equal(t, 5, nodeCount, \"Should have stopped at exactly 5 nodes\")\n}\n\nfunc TestFind_FirstMatch(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM table1 WHERE id > 10;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\t// Find the first FunctionExpr\n\tfound, exists := Find(stmts[0], func(node Expr) bool {\n\t\t_, ok := node.(*FunctionExpr)\n\t\treturn ok\n\t})\n\n\trequire.True(t, exists, \"Should find a FunctionExpr\")\n\trequire.NotNil(t, found)\n\n\tfuncExpr, ok := found.(*FunctionExpr)\n\trequire.True(t, ok, \"Found node should be a FunctionExpr\")\n\trequire.Equal(t, \"COUNT\", Format(funcExpr.Name), \"Should find the COUNT function\")\n}\n\nfunc TestFindAll_MultipleMatches(t *testing.T) {\n\tsql := `SELECT a, COUNT(b), MAX(c) FROM table1 WHERE id > 10;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\t// Find all FunctionExprs\n\tfunctions := FindAll(stmts[0], func(node Expr) bool {\n\t\t_, ok := node.(*FunctionExpr)\n\t\treturn ok\n\t})\n\n\trequire.Equal(t, 2, len(functions), \"Should find 2 function expressions\")\n\n\tfuncNames := make([]string, len(functions))\n\tfor i, fn := range functions {\n\t\tfuncExpr := fn.(*FunctionExpr)\n\t\tfuncNames[i] = Format(funcExpr.Name)\n\t}\n\n\trequire.Contains(t, funcNames, \"COUNT\")\n\trequire.Contains(t, funcNames, \"MAX\")\n}\n\nfunc TestWalk_TableIdentifierRewriting(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\t// Rewrite table names\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tif tableId, ok := node.(*TableIdentifier); ok {\n\t\t\tif Format(tableId.Table) == \"group_by_all\" {\n\t\t\t\ttableId.Table = &Ident{Name: \"hack\"}\n\t\t\t}\n\t\t}\n\t\treturn true\n\t})\n\n\tnewSQL := Format(stmts[0])\n\trequire.Contains(t, newSQL, \"hack\", \"Table name should be rewritten to 'hack'\")\n\trequire.NotContains(t, newSQL, \"group_by_all\", \"Original table name should be gone\")\n}\n\nfunc TestWalk_OrderByDirectionRewriting(t *testing.T) {\n\tsql := `SELECT a, COUNT(b) FROM table1 ORDER BY a ASC, b;`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\t// Change all order directions to DESC\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tif orderExpr, ok := node.(*OrderExpr); ok {\n\t\t\torderExpr.Direction = OrderDirectionDesc\n\t\t}\n\t\treturn true\n\t})\n\n\tnewSQL := Format(stmts[0])\n\trequire.Contains(t, newSQL, string(OrderDirectionDesc), \"Should contain DESC direction\")\n}\n\nfunc TestWalk_NestedQueryDepthTracking(t *testing.T) {\n\tsql := `SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\tvar tableNames []string\n\n\tWalk(stmts[0], func(node Expr) bool {\n\t\t// Track nesting depth\n\t\tif tableID, ok := node.(*JoinTableExpr); ok {\n\t\t\ttableName := Format(tableID.Table)\n\t\t\ttableNames = append(tableNames, tableName+\"@depth\")\n\t\t}\n\t\treturn true\n\t})\n\n\trequire.Len(t, tableNames, 2, \"Should find 2 table identifiers\")\n}\n\nfunc TestWalk_SimpleNodeCounting(t *testing.T) {\n\tsql := `SELECT a FROM table1`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\n\tvar nodeCount int\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tnodeCount++\n\t\treturn true\n\t})\n\n\trequire.Greater(t, nodeCount, 0, \"Walk should visit nodes\")\n\trequire.Greater(t, nodeCount, 3, \"Should visit at least SELECT, column, table nodes\")\n}\n\nfunc TestFind_NoMatch(t *testing.T) {\n\tsql := `SELECT a FROM table1`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\n\t// Try to find a non-existent node type\n\tfound, exists := Find(stmts[0], func(node Expr) bool {\n\t\t// Look for AlterTable in a SELECT statement (should not exist)\n\t\t_, ok := node.(*AlterTable)\n\t\treturn ok\n\t})\n\n\trequire.False(t, exists, \"Should not find AlterTable in SELECT statement\")\n\trequire.Nil(t, found, \"Found node should be nil when not found\")\n}\n\nfunc TestFindAll_EmptyResult(t *testing.T) {\n\tsql := `SELECT a FROM table1`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\n\t// Try to find non-existent node types\n\tresults := FindAll(stmts[0], func(node Expr) bool {\n\t\t// Look for AlterTable in a SELECT statement (should not exist)\n\t\t_, ok := node.(*AlterTable)\n\t\treturn ok\n\t})\n\n\trequire.Empty(t, results, \"Should return empty slice when no matches found\")\n}\n\nfunc TestWalk_ShowStmtNewFields(t *testing.T) {\n\t// Test that Walk properly traverses all new fields in ShowStmt\n\tsql := `SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON`\n\tparser := NewParser(sql)\n\tstmts, err := parser.ParseStmts()\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, len(stmts))\n\n\t_, ok := stmts[0].(*ShowStmt)\n\trequire.True(t, ok, \"Statement should be ShowStmt\")\n\n\t// Collect all nodes during walk\n\tvar foundNodes []Expr\n\tWalk(stmts[0], func(node Expr) bool {\n\t\tfoundNodes = append(foundNodes, node)\n\t\treturn true\n\t})\n\n\t// Should find the ShowStmt itself plus all its expression fields\n\trequire.Greater(t, len(foundNodes), 4, \"Should visit at least ShowStmt + 4 expression fields\")\n\n\t// Find specific types of expressions that should be walked\n\tvar stringLiterals []*StringLiteral\n\tvar numberLiterals []*NumberLiteral\n\n\tfor _, node := range foundNodes {\n\t\tswitch n := node.(type) {\n\t\tcase *StringLiteral:\n\t\t\tstringLiterals = append(stringLiterals, n)\n\t\tcase *NumberLiteral:\n\t\t\tnumberLiterals = append(numberLiterals, n)\n\t\t}\n\t}\n\n\t// Should find exactly 3 string literals: LIKE pattern, OUTFILE path, FORMAT type\n\trequire.Equal(t, 3, len(stringLiterals), \"Should find exactly 3 StringLiteral nodes\")\n\n\t// Should find exactly 1 number literal: LIMIT value\n\trequire.Equal(t, 1, len(numberLiterals), \"Should find exactly 1 NumberLiteral node\")\n\n\t// Verify the specific values\n\tstringValues := make([]string, len(stringLiterals))\n\tfor i, sl := range stringLiterals {\n\t\tstringValues[i] = sl.Literal\n\t}\n\trequire.Contains(t, stringValues, \"prod%\", \"Should contain LIKE pattern\")\n\trequire.Contains(t, stringValues, \"/tmp/prod_dbs.txt\", \"Should contain OUTFILE path\")\n\trequire.Contains(t, stringValues, \"JSON\", \"Should contain FORMAT type\")\n\n\trequire.Equal(t, \"5\", numberLiterals[0].Literal, \"Should contain LIMIT value\")\n}\n"
  }
]