├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── MAINTAINERS ├── README.md ├── examples ├── README.md ├── basic.json ├── complete.json ├── development.json ├── production.json ├── queries.ksql ├── queries │ ├── README.md │ ├── combined.ksql │ ├── hourly-sales.ksql │ ├── item-root.ksql │ ├── one.ksql │ ├── order-root.ksql │ ├── two.ksql │ └── user-root.ksql └── replacements.json ├── package.json ├── src ├── app.js ├── config.js ├── main.js ├── parser │ ├── LICENSE-Grammar │ ├── README.md │ ├── SqlBaseLexer.js │ ├── SqlBaseListener.js │ ├── SqlBaseParser.js │ ├── SyntaxErrorHandler.js │ ├── index.js │ ├── nameExtractor.js │ └── replacer.js └── tests │ ├── config-good.json │ ├── main.spec.js │ ├── queries-bad │ ├── bad-for-clause.ksql │ └── bad-struct.ksql │ └── queries-good │ ├── combined.ksql │ ├── item-root.ksql │ ├── one.ksql │ ├── order-root.ksql │ ├── syntax-tests.ksql │ ├── two.ksql │ └── user-root.ksql ├── webpack.config.js └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | bundle.js 2 | src/parser/SqlBase*.js 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 8, 4 | "ecmaFeatures": { 5 | "jsx": true 6 | }, 7 | "sourceType": "module" 8 | }, 9 | 10 | "env": { 11 | "browser": false, 12 | "es6": false, 13 | "node": true 14 | }, 15 | 16 | "plugins": [], 17 | 18 | "globals": { 19 | "describe": true, 20 | "it": true, 21 | "Promise": true 22 | }, 23 | 24 | "rules": { 25 | "accessor-pairs": "warn", 26 | "arrow-spacing": ["error", { 27 | "before": true, 28 | "after": true 29 | }], 30 | "block-spacing": ["error", "always"], 31 | "brace-style": ["error", "1tbs", { 32 | "allowSingleLine": true 33 | }], 34 | "camelcase": ["warn", { 35 | "properties": "always" 36 | }], 37 | "comma-dangle": [ 38 | "error", 39 | { 40 | "arrays": "never", 41 | "objects": "never", 42 | "imports": "never", 43 | "exports": "never", 44 | "functions": "never" 45 | } 46 | ], 47 | "comma-spacing": ["error", { 48 | "before": false, 49 | "after": true 50 | }], 51 | "comma-style": ["error", "last"], 52 | "constructor-super": "warn", 53 | "curly": ["error", "multi-line"], 54 | "dot-location": ["error", "property"], 55 | "eol-last": "warn", 56 | "eqeqeq": ["error", "always", { 57 | "null": "ignore" 58 | }], 59 | "func-call-spacing": ["error", "never"], 60 | "generator-star-spacing": ["error", { 61 | "before": true, 62 | "after": true 63 | }], 64 | "handle-callback-err": ["warn", "^(err|error)$"], 65 | "indent": ["error", 4], 66 | "key-spacing": ["error", { 67 | "beforeColon": false, 68 | "afterColon": true 69 | }], 70 | "keyword-spacing": ["error", { 71 | "before": true, 72 | "after": true 73 | }], 74 | "new-cap": ["error", { 75 | "newIsCap": true, 76 | "capIsNew": false 77 | }], 78 | "new-parens": "error", 79 | "no-array-constructor": "error", 80 | "no-caller": "error", 81 | "no-class-assign": "error", 82 | "no-compare-neg-zero": "error", 83 | "no-cond-assign": "error", 84 | "no-const-assign": "error", 85 | "no-constant-condition": ["error", { 86 | "checkLoops": false 87 | }], 88 | "no-control-regex": "error", 89 | "no-debugger": "error", 90 | "no-delete-var": "error", 91 | "no-dupe-args": "error", 92 | "no-dupe-class-members": "error", 93 | "no-dupe-keys": "error", 94 | "no-duplicate-case": "error", 95 | "no-duplicate-imports": "error", 96 | "no-empty-character-class": "error", 97 | "no-empty-pattern": "error", 98 | "no-eval": "error", 99 | "no-ex-assign": "error", 100 | "no-extend-native": "warn", 101 | "no-extra-bind": "error", 102 | "no-extra-boolean-cast": "warn", 103 | "no-extra-parens": ["error", "functions"], 104 | "no-fallthrough": "warn", 105 | "no-floating-decimal": "error", 106 | "no-func-assign": "error", 107 | "no-global-assign": "error", 108 | "no-implied-eval": "error", 109 | "no-inner-declarations": ["error", "functions"], 110 | "no-invalid-regexp": "error", 111 | "no-irregular-whitespace": "error", 112 | "no-iterator": "error", 113 | "no-label-var": "error", 114 | "no-labels": ["error", { 115 | "allowLoop": false, 116 | "allowSwitch": false 117 | }], 118 | "no-lone-blocks": "error", 119 | "no-mixed-operators": [ 120 | "error", 121 | { 122 | "groups": [ 123 | ["==", "!=", "===", "!==", ">", ">=", "<", "<="], 124 | ["&&", "||"], 125 | ["in", "instanceof"] 126 | ], 127 | "allowSamePrecedence": true 128 | } 129 | ], 130 | "no-mixed-spaces-and-tabs": "error", 131 | "no-multi-spaces": "error", 132 | "no-multi-str": "error", 133 | "no-multiple-empty-lines": ["error", { 134 | "max": 1, 135 | "maxEOF": 1 136 | }], 137 | "no-new": "error", 138 | "no-new-func": "error", 139 | "no-new-object": "error", 140 | "no-new-require": "error", 141 | "no-new-symbol": "error", 142 | "no-new-wrappers": "error", 143 | "no-obj-calls": "error", 144 | "no-octal": "error", 145 | "no-octal-escape": "error", 146 | "no-path-concat": "error", 147 | "no-proto": "error", 148 | "no-redeclare": "error", 149 | "no-regex-spaces": "warn", 150 | "no-return-assign": ["error", "except-parens"], 151 | "no-return-await": "error", 152 | "no-self-assign": "error", 153 | "no-self-compare": "error", 154 | "no-sequences": "error", 155 | "no-shadow-restricted-names": "error", 156 | "no-sparse-arrays": "error", 157 | "no-tabs": "off", 158 | "no-template-curly-in-string": "error", 159 | "no-this-before-super": "error", 160 | "no-throw-literal": "error", 161 | "no-trailing-spaces": "error", 162 | "no-undef": "error", 163 | "no-undef-init": "error", 164 | "no-unexpected-multiline": "warn", 165 | "no-unmodified-loop-condition": "error", 166 | "no-unneeded-ternary": ["error", { 167 | "defaultAssignment": false 168 | }], 169 | "no-unreachable": "error", 170 | "no-unsafe-finally": "error", 171 | "no-unsafe-negation": "error", 172 | "no-unused-expressions": [ 173 | "error", 174 | { 175 | "allowShortCircuit": true, 176 | "allowTernary": true, 177 | "allowTaggedTemplates": true 178 | } 179 | ], 180 | "no-unused-vars": [ 181 | "error", 182 | { 183 | "vars": "all", 184 | "args": "none", 185 | "ignoreRestSiblings": true 186 | } 187 | ], 188 | "no-use-before-define": [ 189 | "error", 190 | { 191 | "functions": true, 192 | "classes": true, 193 | "variables": true 194 | } 195 | ], 196 | "no-useless-call": "error", 197 | "no-useless-computed-key": "error", 198 | "no-useless-constructor": "error", 199 | "no-useless-escape": "error", 200 | "no-useless-rename": "error", 201 | "no-useless-return": "error", 202 | "no-whitespace-before-property": "error", 203 | "no-with": "error", 204 | "object-property-newline": [ 205 | "error", 206 | { 207 | "allowMultiplePropertiesPerLine": true 208 | } 209 | ], 210 | "one-var": ["error", { 211 | "initialized": "never" 212 | }], 213 | "operator-linebreak": [ 214 | "error", 215 | "after", 216 | { 217 | "overrides": { 218 | "?": "before", 219 | ":": "before" 220 | } 221 | } 222 | ], 223 | "padded-blocks": [ 224 | "error", 225 | { 226 | "blocks": "always", 227 | "switches": "always", 228 | "classes": "always" 229 | } 230 | ], 231 | "prefer-promise-reject-errors": "error", 232 | "quotes": [ 233 | "error", 234 | "single", 235 | { 236 | "avoidEscape": true, 237 | "allowTemplateLiterals": true 238 | } 239 | ], 240 | "rest-spread-spacing": ["error", "never"], 241 | "semi": ["error", "never"], 242 | "semi-spacing": ["error", { 243 | "before": false, 244 | "after": true 245 | }], 246 | "space-before-blocks": ["error", "always"], 247 | "space-before-function-paren": 0, 248 | "space-in-parens": ["error", "never"], 249 | "space-infix-ops": "error", 250 | "space-unary-ops": ["error", { 251 | "words": true, 252 | "nonwords": false 253 | }], 254 | "spaced-comment": [ 255 | "error", 256 | "always", 257 | { 258 | "line": { 259 | "markers": ["*package", "!", "/", ",", "="] 260 | }, 261 | "block": { 262 | "balanced": true, 263 | "markers": [ 264 | "*package", 265 | "!", 266 | ",", 267 | ":", 268 | "::", 269 | "flow-include" 270 | ], 271 | "exceptions": ["*"] 272 | } 273 | } 274 | ], 275 | "symbol-description": "error", 276 | "template-curly-spacing": ["error", "never"], 277 | "template-tag-spacing": ["error", "never"], 278 | "unicode-bom": ["error", "never"], 279 | "use-isnan": "error", 280 | "valid-typeof": ["error", { 281 | "requireStringLiterals": true 282 | }], 283 | "wrap-iife": ["error", "any", { 284 | "functionPrototypeMethods": true 285 | }], 286 | "yield-star-spacing": ["error", "both"], 287 | "yoda": ["error", "never"] 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .nyc_output 2 | bundle.js 3 | coverage 4 | node_modules 5 | test-results.xml 6 | lint.xml 7 | test-results.xml 8 | coverage/ 9 | .*.swp 10 | src/parser/SqlBase.g4 11 | src/parser/*.tokens 12 | src/parser/*.interp 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Initial version maintained by: 2 | Robert Ostensen (https://github.com/robert-ostensen) 3 | Caleb Gerlach (https://github.com/calebgerlach) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KSQL query linter and composer with dependency resolution 2 | 3 | The general purpose of this tool is to lint, perform variable replacement, and compose KSQL 4 | queries from many individual files into a single output file selected by output topics. The 5 | queries in the output file should always be in the correct order for stream/table composition. 6 | For specific details about how query selection and ordering works see the [src/main.js](src/main.js) 7 | file. 8 | 9 | ## Install 10 | 11 | Install globally with [npm](https://nodejs.org/en/docs/meta/topics/dependencies/#npm) 12 | ```bash 13 | npm install -g ksql-query-builder 14 | ``` 15 | or [yarn](https://yarnpkg.com/) 16 | ```bash 17 | yarn global add ksql-query-builder 18 | ``` 19 | 20 | ## Usage 21 | 22 | Basic usage, `ksql-query-builder --topics='output,topics_desired` in a directory with queries will 23 | read and parse all queries found in the current directory or below then output all the queries 24 | necessary to generate the `output` and `topics_desired` topics. To use replacements, create a 25 | [json file](config.json) with the replacement property set to an object, see [#replacements] for 26 | details. To only lint all the queries in a directory use `--lint`. 27 | 28 | # Example output 29 | 30 | See [examples/queries.ksql](examples/queries.ksql) for an example of what the formatted and ordered 31 | queries look like. 32 | 33 | ### Replacements 34 | 35 | At this time any property set in a `WITH` block and timezone specifiers can be replaced. To perform 36 | parameter replacement create a config file: 37 | ```json 38 | { 39 | "replacements": { 40 | "with/partitions": 2, 41 | "with/VALUE_FORMAT": "'JSON'", 42 | "time zone": "'new time zone'", 43 | "function/timestamptostring/tz": "'UTC'" 44 | }, 45 | "queries": ["order_total"] 46 | } 47 | ``` 48 | the property name of the replacement is structured like a path and the value is used without 49 | interpolation. If the value needs quoting in the query you must include the quotes in the json. 50 | Property names are case insensitive. 51 | 52 | ### Automation 53 | 54 | This tool was developed specifically to support automation workflows, the `--lint` option should 55 | work the way most other linting tools do in a CI/CD pipeline. For deployments to different 56 | environments that need different scaling performance set the PARTITIONS accordingly, for example 57 | use 1 PARTITION for a development environment and 3 PARTITIONS for production. The output of 58 | every run should have a unique checksum because the first line is a comment with the ISO time the 59 | output was generated, removing that line should generate consistent files given the same input. 60 | 61 | See [examples](examples/README.md) for details, including a suggested development vs production 62 | workflow. 63 | 64 | ### Library usage 65 | 66 | This package can be used as a dependency, you will need to pass in a configuration 67 | object the the exported `run` method. See [src/app.js](src/app.js) for an example of how it works. 68 | 69 | ### Limitations 70 | 71 | Only statements that create topics/streams will be included in the output, if you need drop 72 | statements or other statements for setup(eg `SET 'value' = ...`) you will need to prepend them to the output. 73 | 74 | ## Configuration 75 | 76 | Options can be specified via the command line in the form `--arg=value`, as environment 77 | variables, or in a [config file](examples/README.md) 78 | * `--queries` or `QUERIES_PATH` - The path to the KSQL queries defaults to `./`, use absolute 79 | or relative path, relative paths are resolved relative to the config.json file or `$PWD` 80 | * `--config` or `QUERIES_CONFIG` - The path to the configuration file you would like to use 81 | * `--output` or `OUTPUT` - The path to the file you would like to save the output 82 | queries in, if unset and not in linting mode queries are sent to STDOUT 83 | * `--topics` or `TOPICS` - List of comma-separated topics that you want to have populated, 84 | these are the target topics that will generate output data, the tool will select all the 85 | necessary dependencies and output them in the correct order. N.B. All other topics will *not* 86 | be included in the ouput. 87 | * `--lint` - turns on linting mode which disables writing queries to a file, default off 88 | 89 | an example would be 90 | 91 | myconfig.json 92 | ```json 93 | { 94 | "replacements": {"with/partitions":2}, 95 | "queries": ["order_total"] 96 | } 97 | ``` 98 | 99 | ```bash 100 | yarn generate --queries=path/to/queries/relative/to/config/ --config=myconfig.json --output=queries.ksql 101 | ``` 102 | 103 | ## Syntax Errors and Linting 104 | 105 | In all cases of syntax error the program will exit without writing a query file. When a 106 | syntax error is encountered in a file the output will be something like 107 | 108 | ```console 109 | $ yarn generate --queries=tests/queries-bad/ --config=tests/config-good.json --output=queries.ksql 110 | yarn run v1.21.0 111 | $ node ./src/app.js --queries=queries-bad --config=src/tests/config-good.json --output=queries.ksql 112 | =============================================================================================================================================================== 113 | Error parsing file: queries-bad/bad-for-clause.ksql 114 | Error at column 22 on line 1 115 | 116 | SELECT * FROM bar b ON (a.id=b.id) 117 | ^ 118 | mismatched input 'ON' expecting ';' 119 | 120 | 121 | 122 | =============================================================================================================================================================== 123 | Error parsing file: queries-bad/bad-struct.ksql 124 | Error at column 96 on line 0 125 | 126 | CREATE STREAM pageviews (viewtime BIGINT, user_id VARCHAR, page_id VARCHAR, `Properties` VARCHAR>) 127 | ^ 128 | extraneous input '>' expecting {',', ')'} 129 | 130 | 131 | 132 | Done in 0.21s. 133 | ``` 134 | 135 | ## KSQL language updates 136 | 137 | see [README.md](src/parser/README.md) in the parser directory for grammar 138 | update instructions 139 | 140 | ## License 141 | 142 | Copyright 2019 Carnegie Technologies 143 | 144 | Licensed under the Apache License, Version 2.0 (the "License"); 145 | you may not use this file except in compliance with the License. 146 | You may obtain a copy of the License at 147 | 148 | http://www.apache.org/licenses/LICENSE-2.0 149 | 150 | Unless required by applicable law or agreed to in writing, software 151 | distributed under the License is distributed on an "AS IS" BASIS, 152 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 153 | See the License for the specific language governing permissions and 154 | limitations under the License. 155 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example configurations and usage 2 | 3 | # Example output 4 | 5 | [queries.ksql](queries.ksql) contains the ouput of `ksql-query-builder --config=complete.json` 6 | 7 | ## Configuration 8 | 9 | Example configuration files and [queries](./queries/README.md) 10 | 11 | * [basic.json](basic.json) - very basic example, only selects one output topicc 12 | * [development.json](development.json) - example of a development file vs production 13 | * [production.json](production.json) - exmaple of a production file vs development 14 | * [replacements.json](replacements.json) - examples of currently supported replacements 15 | * [complete.json](complete.json) - combination of the above, shows all the properties set 16 | 17 | ## example development/production workflow 18 | ```bash 19 | ksql-query-builder --config=development.json | tee queries.json 20 | # vs 21 | ksql-query-builder --config=production.json || exit 22 | ``` 23 | 24 | ## Replacements 25 | 26 | Replacements occur for all statements that have a matching feature, if you need replace text in 27 | specific queries preprocess them using different tool then compose them together with 28 | ksql-query-builder. 29 | 30 | The property name of the replacement is structured like a path and the value is used without 31 | interpolation. If the value needs quoting in the query you must include the quotes in the json. 32 | Property names are case insensitive. 33 | 34 | At this time any property set in a `WITH` block and timezone specifiers can be replaced using 35 | `with/NAME` where `NAME` is any property set inside a `WITH(...)`. 36 | 37 | ### Future goals (feedback welcome!) 38 | 39 | * support generic function parameter replacement in the form `function/name/number` where the `name` 40 | is a function name and `number` is the position of the parameter you want to replace. 41 | * support additional features like window sizes eg `"window/size": "30 MINUTES"` and methods 42 | `"window/advance": "30 SECONDS"`. 43 | -------------------------------------------------------------------------------- /examples/basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "topics": ["order_total"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/complete.json: -------------------------------------------------------------------------------- 1 | { 2 | "lint": false, 3 | "output": "queries.ksql", 4 | "queriesPath": "./queries/", 5 | "replacements": { 6 | "TIME ZONE": "'UTC'", 7 | "FUNCTION/TIMESTAMPTOSTRING/TZ": "'Europe/London'", 8 | "with/value_format": "'AVRO'", 9 | "with/partitions": 2 10 | }, 11 | "topics": [ 12 | "order_total", 13 | "hourly_sales" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/development.json: -------------------------------------------------------------------------------- 1 | { 2 | "queriesPath": "./queries/", 3 | "replacements": {"with/partitions":1}, 4 | "topics": ["order_total"] 5 | } 6 | -------------------------------------------------------------------------------- /examples/production.json: -------------------------------------------------------------------------------- 1 | { 2 | "lint": false, 3 | "output": "queries.ksql", 4 | "queriesPath": "./queries/", 5 | "replacements": {"with/partitions":3}, 6 | "topics": ["order_total"] 7 | } 8 | -------------------------------------------------------------------------------- /examples/queries.ksql: -------------------------------------------------------------------------------- 1 | --- queries generated on 2019-12-05T19:04:06.870Z 2 | --- from file: queries/item-root.ksql statement: 1 3 | CREATE STREAM items( 4 | time VARCHAR, 5 | name VARCHAR, 6 | price BIGINT) 7 | WITH( 8 | KAFKA_TOPIC='items-in', 9 | VALUE_FORMAT='AVRO', 10 | TIMESTAMP='rawTime', 11 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 12 | KEY='id'); 13 | --- from file: queries/order-root.ksql statement: 1 14 | CREATE STREAM orders( 15 | id BIGINT, 16 | user BIGINT, 17 | item STRING, 18 | quantity INTEGER) 19 | WITH( 20 | KAFKA_TOPIC='orders-in', 21 | VALUE_FORMAT='AVRO', 22 | TIMESTAMP='rawTime', 23 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 24 | KEY='id'); 25 | --- from file: queries/hourly-sales.ksql statement: 1 26 | CREATE TABLE hourly_sales 27 | WITH( 28 | VALUE_FORMAT='AVRO', 29 | PARTITIONS=2) AS 30 | SELECT 31 | COUNT(*) AS orders, 32 | SUM(i.price * o.quantity) AS total_sales 33 | FROM orders o JOIN 34 | items i ON(o.itemname=i.name) 35 | WINDOW HOPPING(SIZE 1 HOUR, ADVANCE BY 1 HOUR) 36 | GROUP BY o.id; 37 | --- from file: queries/one.ksql statement: 1 38 | CREATE STREAM orders_items 39 | WITH( 40 | VALUE_FORMAT='AVRO') AS 41 | SELECT 42 | o.id AS order_id, 43 | i.price AS item_price 44 | FROM orders o JOIN 45 | items i ON(o.itemname=i.name); 46 | --- from file: queries/user-root.ksql statement: 1 47 | CREATE STREAM users( 48 | id BIGINT, 49 | name VARCHAR, 50 | email STRING) 51 | WITH( 52 | KAFKA_TOPIC='users-in', 53 | VALUE_FORMAT='AVRO', 54 | TIMESTAMP='rawTime', 55 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 56 | KEY='id'); 57 | --- from file: queries/two.ksql statement: 2 58 | CREATE STREAM orders_users 59 | WITH( 60 | VALUE_FORMAT='AVRO') AS 61 | SELECT 62 | o.id AS order_id, 63 | u.name AS user_name, 64 | u.email AS email, 65 | o.item AS item_name, 66 | o.quantity AS quantity 67 | FROM orders o JOIN 68 | users u ON(o.user=u.id); 69 | --- from file: queries/combined.ksql statement: 1 70 | CREATE TABLE order_total 71 | WITH( 72 | VALUE_FORMAT='AVRO', 73 | PARTITIONS=2) AS 74 | SELECT 75 | u.order_id AS order_id, 76 | u.user_name AS username, 77 | u.email AS email, 78 | i.price * u.quantity AS total 79 | FROM orders_users u LEFT JOIN 80 | orders_items i ON(u.order_id=i.order_id) 81 | GROUP BY u.order_id; -------------------------------------------------------------------------------- /examples/queries/README.md: -------------------------------------------------------------------------------- 1 | # Example queries 2 | 3 | These are mostly useless queries to show how the tool works. 4 | 5 | * [combined.ksql](combined.ksql) - combines output from the combined streams joining items, 6 | orders, and users. 7 | * [hourly-sales.ksql](hourly-sales.ksql) - joins items and orders and outputs 1 row per hour, 8 | example of how multiple queries can depend on the same input(combined.ksql). 9 | * [item-root.ksql](item-root.ksql) - creates a stream from a topic 10 | * [one.ksql](one.ksql) - combines items and orders 11 | * [order-root.ksql](order-root.ksql) - creates a stream from a topic 12 | * [two.ksql](two.ksql) - has example of debug query that will not be in the output, 13 | combines orders and users 14 | * [user-root.ksql](user-root.ksql) - creates a stream from a topic 15 | -------------------------------------------------------------------------------- /examples/queries/combined.ksql: -------------------------------------------------------------------------------- 1 | CREATE TABLE order_total WITH (VALUE_FORMAT='AVRO',PARTITIONS=1) 2 | AS SELECT 3 | u.order_id AS order_id, 4 | u.user_name AS username, 5 | u.email AS email, 6 | i.price * u.quantity AS total 7 | FROM 8 | orders_users u 9 | LEFT JOIN orders_items i ON (u.order_id = i.order_id) 10 | GROUP BY u.order_id 11 | ; -------------------------------------------------------------------------------- /examples/queries/hourly-sales.ksql: -------------------------------------------------------------------------------- 1 | --- create hourly sales numbers 2 | CREATE TABLE hourly_sales WITH (VALUE_FORMAT='AVRO',PARTITIONS=1) 3 | AS SELECT 4 | COUNT(*) AS orders, 5 | SUM(i.price * o.quantity) AS total_sales 6 | FROM 7 | orders o 8 | JOIN items i ON (o.itemname=i.name) 9 | WINDOW HOPPING (SIZE 1 HOUR, ADVANCE BY 1 HOUR) 10 | GROUP BY o.id 11 | ; -------------------------------------------------------------------------------- /examples/queries/item-root.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM items ( 2 | time VARCHAR, 3 | name VARCHAR, 4 | price BIGINT) 5 | WITH (KAFKA_TOPIC = 'items-in', 6 | VALUE_FORMAT='JSON', 7 | TIMESTAMP='rawTime', 8 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 9 | KEY = 'id'); 10 | -------------------------------------------------------------------------------- /examples/queries/one.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM orders_items WITH (VALUE_FORMAT='AVRO') 2 | AS SELECT 3 | o.id AS order_id, 4 | i.price AS item_price 5 | FROM 6 | orders o 7 | JOIN items i ON (o.itemname=i.name) 8 | ; -------------------------------------------------------------------------------- /examples/queries/order-root.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM orders ( 2 | id BIGINT, 3 | user BIGINT, 4 | item STRING, 5 | quantity INTEGER) 6 | WITH (KAFKA_TOPIC = 'orders-in', 7 | VALUE_FORMAT='JSON', 8 | TIMESTAMP='rawTime', 9 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 10 | KEY = 'id'); 11 | -------------------------------------------------------------------------------- /examples/queries/two.ksql: -------------------------------------------------------------------------------- 1 | --- example debug query, this will not be in the output 2 | SELECT order_id, email FROM orders_users LIMIT 5; 3 | --- the actual query we will use 4 | CREATE STREAM orders_users WITH (VALUE_FORMAT='AVRO') 5 | AS SELECT 6 | o.id AS order_id, 7 | u.name AS user_name, 8 | u.email AS email, 9 | o.item AS item_name, 10 | o.quantity AS quantity 11 | FROM 12 | orders o 13 | JOIN users u ON (o.user = u.id); -------------------------------------------------------------------------------- /examples/queries/user-root.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM users ( 2 | id BIGINT, 3 | name VARCHAR, 4 | email STRING) 5 | WITH (KAFKA_TOPIC = 'users-in', 6 | VALUE_FORMAT='JSON', 7 | TIMESTAMP='rawTime', 8 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 9 | KEY = 'id'); 10 | -------------------------------------------------------------------------------- /examples/replacements.json: -------------------------------------------------------------------------------- 1 | { 2 | "queriesPath": "./queries/", 3 | "replacements": { 4 | "TIME ZONE": "'UTC'", 5 | "FUNCTION/TIMESTAMPTOSTRING/TZ": "'Europe/London'", 6 | "with/value_format": "'AVRO'", 7 | "with/partitions": 2 8 | }, 9 | "topics": ["order_total"] 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ksql-query-builder", 3 | "version": "1.0.0", 4 | "bin": "src/app.js", 5 | "main": "src/main.js", 6 | "sideEffects": false, 7 | "license": "Apache-2.0", 8 | "engines": { 9 | "node": ">=12.0" 10 | }, 11 | "scripts": { 12 | "lint": "eslint . --fix", 13 | "test": "nyc mocha --reporter spec", 14 | "bundle": "webpack-cli", 15 | "generate": "node ./src/app.js", 16 | "grammar": "cd src/parser; antlr4 -Dlanguage=JavaScript SqlBase.g4 && rm *.tokens *.interp" 17 | }, 18 | "mocha": { 19 | "spec": "src/tests/**/*.spec.js", 20 | "reporter": "mocha-junit-reporter" 21 | }, 22 | "nyc": { 23 | "reporter": [ 24 | "text", 25 | "html" 26 | ], 27 | "check-coverage": true, 28 | "lines": 70, 29 | "statements": 70 30 | }, 31 | "devDependencies": { 32 | "capture-console": "^1.0.1", 33 | "eslint": "^5.16.0", 34 | "eslint-config-recommended": "^4.0.0", 35 | "expect.js": "^0.3.1", 36 | "mocha": "^6.1.4", 37 | "mocha-junit-reporter": "^1.22.0", 38 | "nyc": "^14.1.0", 39 | "webpack": "^4.36.1", 40 | "webpack-cli": "^3.3.6" 41 | }, 42 | "dependencies": { 43 | "antlr4": "^4.7.2", 44 | "convict": "^4.4.1" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | Copyright 2019 Carnegie Technologies 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | ***********************************************************************/ 16 | 17 | if (process.env.PWD !== process.cwd()) { 18 | 19 | process.chdir(process.env.PWD) 20 | 21 | } 22 | const config = require('./config') 23 | const main = require('./main') 24 | 25 | main 26 | .run(config) 27 | .then(text => { 28 | 29 | if (config.get('lint')) { 30 | 31 | text && console.log('Syntax OK') 32 | return 33 | 34 | } 35 | if (text && !config.get('output')) { 36 | 37 | console.log(text) 38 | 39 | } 40 | 41 | }) 42 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Sets up the configuration manager and any validation functions it needs 3 | */ 4 | const convict = require('convict') 5 | const path = require('path') 6 | 7 | /** The configuration to provide to the generator */ 8 | var config = convict({ 9 | queriesPath: { 10 | doc: 'The path to the KSQL queries', 11 | format: 'String', 12 | default: './', 13 | arg: 'queries', 14 | env: 'QUERIES_PATH' 15 | }, 16 | configFile: { 17 | doc: 'The path to the configuration file you would like to use to configure for this deployment', 18 | format: 'String', 19 | default: 'false', 20 | arg: 'config', 21 | env: 'QUERIES_CONFIG' 22 | }, 23 | output: { 24 | doc: 'The path to the file you would like to save the output queries in', 25 | format: 'String', 26 | default: '', 27 | arg: 'output', 28 | env: 'OUTPUT' 29 | }, 30 | lint: { 31 | doc: 'Exit on Syntax Errors', 32 | format: 'Boolean', 33 | arg: 'lint', 34 | default: false 35 | }, 36 | topics: { 37 | doc: 'Array of the names of topics we want to generate', 38 | format: 'Array', 39 | default: [], 40 | arg: 'topics', 41 | env: 'TOPICS' 42 | }, 43 | replacements: { 44 | doc: 'Replacements to make in the generated queries', 45 | format: 'Object', 46 | default: {} 47 | } 48 | }) 49 | 50 | if (config.get('configFile') !== 'false') { 51 | 52 | config.loadFile(path.resolve(process.cwd(), config.get('configFile'))) 53 | 54 | if (!config.get('configFile').startsWith('/')) { 55 | 56 | // set working directory to the directory the config file is in 57 | process.chdir(path.dirname(path.resolve(process.cwd(), config.get('configFile')))) 58 | 59 | } 60 | 61 | } 62 | 63 | module.exports = config 64 | config.validate({ 65 | allowed: 'strict' 66 | }) 67 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | Copyright 2019 Carnegie Technologies 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | ***********************************************************************/ 16 | 17 | const parser = require('./parser/index.js') 18 | const fs = require('fs').promises 19 | const path = require('path') 20 | 21 | // make the config a variable, testing and reuse are easier if it's passed in 22 | var config 23 | 24 | // nicely print KSQL query parsing errors 25 | function prettyPrintError(filename, text, error) { 26 | 27 | const lines = text.split('\n') 28 | const errorLineNum = error.row 29 | let errorLineOut = '' 30 | let errorLine = lines[error.row] 31 | let errorCol = error.column 32 | const width = process.stdout.columns || 80 33 | while (errorCol > width) { 34 | 35 | errorLineOut += errorLine.slice(0, width) + '\n' 36 | errorLine = errorLine.slice(width) 37 | errorCol -= width 38 | 39 | } 40 | errorLineOut = 'Error at column ' + error.column + ' on line ' + errorLineNum + '\n' + 41 | errorLineOut.replace(/\s*\n*$/g, '') + '\n' + 42 | errorLine.slice(0, width > errorCol ? width : -1) 43 | console.error(errorLineOut) 44 | console.error(Array(errorCol < 0 ? width - errorCol : errorCol).join(' ') + '^') 45 | console.error(error.text, '\n') 46 | 47 | } 48 | 49 | // recursively read all *.ksql files from the given directory 50 | // read said files and perform variable replacement 51 | // parse the ksql from the replaced text of those files 52 | // add the file text and parsed AST to the ksqlmap object 53 | // if errors parsing, pretty print errors and throw 54 | async function getFiles(dir, replacements, ksqlmap) { 55 | 56 | const contents = await fs.readdir(dir, { 57 | withFileTypes: true 58 | }) 59 | var exit = false 60 | await Promise.all(contents 61 | .filter(file => !(/^\.+$/).test(file.name)) 62 | .map(async(file) => { 63 | 64 | if (file.isFile() && /\.ksql$/i.test(file.name)) { 65 | 66 | const name = path.join(dir, file.name) 67 | var ast 68 | try { 69 | 70 | const text = await fs.readFile(name, 'utf8') 71 | ast = parser.parse(text) 72 | const statements = ast.statements() 73 | // do a pass to grab all the syntax errors 74 | parser.readRelations(statements) 75 | // the annotations will contain and parsing errors 76 | if (ast.annotations.length > 0) { 77 | 78 | exit = true 79 | console.error(Array((process.stdout.columns || 80)).join('=')) 80 | console.error('Error parsing file:', name.trim()) 81 | ast.annotations.forEach(a => 82 | prettyPrintError(name, text, a) 83 | ) 84 | console.error('\n') 85 | 86 | } 87 | 88 | // loop over statements so we can filter them individually 89 | for (let i = 0; i < statements.children.length; i++) { 90 | 91 | // statement has no children it's empty, skip it 92 | if (!statements.children[i] || !statements.children[i].children) continue 93 | 94 | const statementName = `${name} statement: ${i + 1}` 95 | // the relations will contain the source and sink topics 96 | ksqlmap[statementName] = parser.readRelations(statements.children[i]) 97 | 98 | ksqlmap[statementName].text = parser.replace(statements.children[i], replacements) 99 | ksqlmap[statementName].tree = statements.children[i] 100 | 101 | } 102 | 103 | } catch (e) { 104 | 105 | // we probably had a file read error or parser crash error 106 | // to get here 107 | 108 | exit = true 109 | if (ast.annotations.length === 0) { 110 | 111 | console.error('error handling file', name, e) 112 | 113 | } 114 | 115 | } 116 | 117 | } 118 | // recursion to hit all the subdirectories 119 | if (file.isDirectory()) { 120 | 121 | await getFiles(path.join(dir, file.name), replacements, ksqlmap) 122 | 123 | } 124 | 125 | })) 126 | if (exit) { 127 | 128 | throw new Error('Error parsing files') 129 | 130 | } 131 | return true 132 | 133 | } 134 | 135 | // where the magic happens 136 | // we build a depenency map of the queries using the sink/source topics 137 | // select the topics we have been asked to generate from the config(topics) 138 | // use that list to work backwards up the tree and prune everything that we 139 | // didn't touch. using the list of queries we have left work from the source 140 | // topic(s) down in dependency order, flatten then dedup keeping the first 141 | // entry of a duplicated query. Finally map the selected queries in the 142 | // sorted order into the output text prefacing each file with a comment 143 | // including the filename then the text(with replacements) of the file itself 144 | async function sortedQueries(ksqlmap) { 145 | 146 | const contents = {} 147 | const depends = {} 148 | let includedQueries = [] 149 | let rootQueries = [] 150 | 151 | // build dependency tree 152 | function getDeps(query) { 153 | 154 | return contents[query] 155 | .filter(q => !!contents[q]) 156 | .map(q => getDeps(q)) 157 | .sort() 158 | .concat(contents[query]) 159 | 160 | } 161 | 162 | // helper for walking up the tree 163 | function getParents() { 164 | 165 | return Object.keys(depends) 166 | .map(q => [q].concat(depends[q])) 167 | 168 | } 169 | 170 | // get array of all child queries 171 | function getChildren(query) { 172 | 173 | return Object.keys(includedQueries) 174 | .filter(q => includedQueries[q] && includedQueries[q].includes(query)) 175 | .map(q => [q].concat(getChildren(q))) 176 | 177 | } 178 | 179 | // get array of all children of root queries 180 | function getAllChildren() { 181 | 182 | return Object.keys(includedQueries) 183 | .filter(q => rootQueries.includes(q)) 184 | .map(getChildren) 185 | .reduce((p, c) => p.concat(c.flat(Infinity)), []) 186 | 187 | } 188 | 189 | // convert the list of files in to something easier to operate on, specifically 190 | // we are creating an object with output topics as keys and source topics as values 191 | Object.keys(ksqlmap).forEach(query => { 192 | 193 | ksqlmap[query].created.forEach(source => { 194 | 195 | if (ksqlmap[query].from) { 196 | 197 | contents[source.toLowerCase()] = ksqlmap[query].from.map(q => q.toLowerCase()) 198 | 199 | } 200 | 201 | }) 202 | 203 | if (ksqlmap[query].fromTopic) { 204 | 205 | rootQueries.push(ksqlmap[query].from[0]) 206 | 207 | } 208 | 209 | }) 210 | 211 | // select output queries we want to generate 212 | // KSQL case is a little odd so just lowercase everything 213 | // and also grab all of it's dependencies 214 | const lowerCaseQueries = config.get('topics') 215 | .map(q => q.toLowerCase().trim()) 216 | .sort() 217 | Object.keys(contents) 218 | .forEach(query => { 219 | 220 | if (lowerCaseQueries.includes(query.toLowerCase().trim())) { 221 | 222 | depends[query.toLowerCase().trim()] = getDeps(query) 223 | 224 | } 225 | 226 | }) 227 | 228 | // filter the full list of topics to just the ones we have been 229 | // asked to generate as output topics 230 | includedQueries = getParents() 231 | .flat(Infinity) 232 | .sort() 233 | .reduce((prev, cur) => Object.assign(prev, { 234 | [cur]: contents[cur] 235 | }), {}) 236 | 237 | // generate list of topics in the correct order 238 | const order = getAllChildren() 239 | .flat(Infinity) 240 | .filter((cur, idx, arr) => !arr.slice(idx + 1).includes(cur)) 241 | 242 | // convert ordered list of queries from ordered list of topics 243 | // sort the keys to make the output consistent across runs 244 | const queries = order.map(q => Object.keys(ksqlmap).sort().filter(k => ksqlmap[k].created.includes(q))).flat(Infinity) 245 | 246 | // we can still get duplicates here so filter out items that appear earlier in the list 247 | const dedupedQueries = queries.filter((cur, idx, arr) => !arr.slice(0, idx).includes(cur)) 248 | 249 | // map filenames into the text of those files 250 | const text = '--- queries generated on ' + (new Date()).toISOString() + '\n' + 251 | dedupedQueries.map(q => `--- from file: ${q}\n` + ksqlmap[q].text).join('\n') 252 | const output = config.get('output') 253 | if (String(process.env.LOG_LEVEL).toLowerCase() === 'debug') { 254 | 255 | console.error('includedQueries:', JSON.stringify(includedQueries)) 256 | console.error('order:', JSON.stringify(order)) 257 | console.error('queries:', JSON.stringify(queries)) 258 | console.error('dedupedQueries:', JSON.stringify(dedupedQueries)) 259 | console.error('dedupedQueries:', JSON.stringify(lowerCaseQueries)) 260 | 261 | } 262 | // in KSQL linting mode do not write a queries file 263 | if (String(output).length) { 264 | 265 | fs.writeFile(output, text) 266 | console.error('wrote queries to', output) 267 | 268 | } 269 | 270 | // always return the text of the rendered queries in order 271 | return text 272 | 273 | } 274 | 275 | // main entry point 276 | exports.run = async function (conf) { 277 | 278 | config = conf 279 | 280 | const ksqlmap = {} 281 | 282 | const replacements = config.get('replacements') || {} 283 | 284 | try { 285 | 286 | await getFiles(config.get('queriesPath'), replacements, ksqlmap) 287 | 288 | } catch (error) { 289 | 290 | if (config.get('lint') === true) { 291 | 292 | process.exit(-1) 293 | 294 | } 295 | if (error.code === 'ENOENT') { 296 | 297 | console.error('Error directory', config.get('queriesPath'), 'does not exist') 298 | 299 | } 300 | return false 301 | 302 | } 303 | return sortedQueries(ksqlmap) 304 | 305 | } 306 | -------------------------------------------------------------------------------- /src/parser/LICENSE-Grammar: -------------------------------------------------------------------------------- 1 | Confluent Community License Agreement 2 | Version 1.0 3 | 4 | This Confluent Community License Agreement Version 1.0 (the “Agreement”) sets 5 | forth the terms on which Confluent, Inc. (“Confluent”) makes available certain 6 | software made available by Confluent under this Agreement (the “Software”).  BY 7 | INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, 8 | YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO 9 | SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE.  IF YOU ARE RECEIVING 10 | THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU 11 | HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS 12 | AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or 13 | the entity on whose behalf you are receiving the Software. 14 | 15 | 1. LICENSE GRANT AND CONDITIONS. 16 | 17 | 1.1 License.  Subject to the terms and conditions of this Agreement, 18 | Confluent hereby grants to Licensee a non-exclusive, royalty-free, 19 | worldwide, non-transferable, non-sublicenseable license during the term 20 | of this Agreement to: (a) use the Software; (b) prepare modifications and 21 | derivative works of the Software; (c) distribute the Software (including 22 | without limitation in source code or object code form); and (d) reproduce 23 | copies of the Software (the “License”).  Licensee is not granted the 24 | right to, and Licensee shall not, exercise the License for an Excluded 25 | Purpose.  For purposes of this Agreement, “Excluded Purpose” means making 26 | available any software-as-a-service, platform-as-a-service, 27 | infrastructure-as-a-service or other similar online service that competes 28 | with Confluent products or services that provide the Software. 29 | 30 | 1.2 Conditions.  In consideration of the License, Licensee’s distribution 31 | of the Software is subject to the following conditions: 32 | 33 | (a) Licensee must cause any Software modified by Licensee to carry 34 | prominent notices stating that Licensee modified the Software. 35 | 36 | (b) On each Software copy, Licensee shall reproduce and not remove or 37 | alter all Confluent or third party copyright or other proprietary 38 | notices contained in the Software, and Licensee must provide the 39 | notice below with each copy.   40 | 41 | “This software is made available by Confluent, Inc., under the 42 | terms of the Confluent Community License Agreement, Version 1.0 43 | located at http://www.confluent.io/confluent-community-license.  BY 44 | INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF 45 | THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.” 46 | 47 | 1.3 Licensee Modifications.  Licensee may add its own copyright notices 48 | to modifications made by Licensee and may provide additional or different 49 | license terms and conditions for use, reproduction, or distribution of 50 | Licensee’s modifications.  While redistributing the Software or 51 | modifications thereof, Licensee may choose to offer, for a fee or free of 52 | charge, support, warranty, indemnity, or other obligations. Licensee, and 53 | not Confluent, will be responsible for any such obligations. 54 | 55 | 1.4 No Sublicensing.  The License does not include the right to 56 | sublicense the Software, however, each recipient to which Licensee 57 | provides the Software may exercise the Licenses so long as such recipient 58 | agrees to the terms and conditions of this Agreement.   59 | 60 | 2. TERM AND TERMINATION.  This Agreement will continue unless and until 61 | earlier terminated as set forth herein.  If Licensee breaches any of its 62 | conditions or obligations under this Agreement, this Agreement will 63 | terminate automatically and the License will terminate automatically and 64 | permanently. 65 | 66 | 3. INTELLECTUAL PROPERTY.  As between the parties, Confluent will retain all 67 | right, title, and interest in the Software, and all intellectual property 68 | rights therein.  Confluent hereby reserves all rights not expressly granted 69 | to Licensee in this Agreement. Confluent hereby reserves all rights in its 70 | trademarks and service marks, and no licenses therein are granted in this 71 | Agreement. 72 | 73 | 4. DISCLAIMER.  CONFLUENT HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND 74 | CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY 75 | DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR 76 | PURPOSE, WITH RESPECT TO THE SOFTWARE.   77 | 78 | 5. LIMITATION OF LIABILITY.  CONFLUENT WILL NOT BE LIABLE FOR ANY DAMAGES OF 79 | ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, 80 | SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY 81 | THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT.  THE FOREGOING SHALL 82 | APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW. 83 | 84 | 6.GENERAL. 85 | 86 | 6.1 Governing Law. This Agreement will be governed by and interpreted in 87 | accordance with the laws of the state of California, without reference to 88 | its conflict of laws principles.  If Licensee is located within the 89 | United States, all disputes arising out of this Agreement are subject to 90 | the exclusive jurisdiction of courts located in Santa Clara County, 91 | California. USA.  If Licensee is located outside of the United States, 92 | any dispute, controversy or claim arising out of or relating to this 93 | Agreement will be referred to and finally determined by arbitration in 94 | accordance with the JAMS International Arbitration Rules.  The tribunal 95 | will consist of one arbitrator. The place of arbitration will be Palo 96 | Alto, California. The language to be used in the arbitral proceedings 97 | will be English. Judgment upon the award rendered by the arbitrator may 98 | be entered in any court having jurisdiction thereof. 99 | 100 | 6.2 Assignment.  Licensee is not authorized to assign its rights under 101 | this Agreement to any third party. Confluent may freely assign its rights 102 | under this Agreement to any third party. 103 | 104 | 6.3 Other.  This Agreement is the entire agreement between the parties 105 | regarding the subject matter hereof.  No amendment or modification of 106 | this Agreement will be valid or binding upon the parties unless made in 107 | writing and signed by the duly authorized representatives of both 108 | parties.  In the event that any provision, including without limitation 109 | any condition, of this Agreement is held to be unenforceable, this 110 | Agreement and all licenses and rights granted hereunder will immediately 111 | terminate.  Waiver by Confluent of a breach of any provision of this 112 | Agreement or the failure by Confluent to exercise any right hereunder 113 | will not be construed as a waiver of any subsequent breach of that right 114 | or as a waiver of any other right. 115 | -------------------------------------------------------------------------------- /src/parser/README.md: -------------------------------------------------------------------------------- 1 | # KSQL parser 2 | 3 | We use the grammar from the KSQL project compiled to javascript to handle parsing, dependency 4 | extraction and resolution, pretty printing, and replacement(eg, partitions/timezones). 5 | 6 | 7 | ## Guidelines 8 | 9 | Due to the way antlr4 generated output is consumed we should not modify generated files, they 10 | serve as the base to inherit from and should not be modified after being generated or updated. 11 | The general concept we are working with is the extraction of what stream each query provides and 12 | which streams are consumed. That data allows us to generate a file with queries order by their 13 | dependencies. Additionally we also know that the specific syntax of each query is correct because 14 | the same parser code should be used by the server, this does *not* imply that the queries will 15 | all work without errors only that they are syntactically correct according to the KSQL grammar. 16 | 17 | ## Updates 18 | to update the grammar grab the latest version of SqlBase.g4 from the 19 | [ksql source](https://github.com/confluentinc/ksql/blob/master/ksql-parser/src/main/antlr4/io/confluent/ksql/parser/SqlBase.g4) 20 | and place it in this directory. 21 | 22 | run antlr4: 23 | ```bash 24 | antlr4 -Dlanguage=JavaScript SqlBase.g4 25 | ``` 26 | or in the project root run 27 | ```bash 28 | yarn grammar 29 | ``` 30 | *NOTE*: the grammar may need to be tweaked to allow lowercase identifiers by adding `a-z` to the 31 | definition of `fragment LETTER` 32 | 33 | ## License 34 | 35 | Copyright 2019 Carnegie Technologies 36 | 37 | Sources generated by antlr4 are derivative works of the upstream SqlBase.g4 which is licensed 38 | under the [Confluent Community License](https://www.confluent.io/confluent-community-license/) [also here](./LICENSE-Grammar). 39 | 40 | Everything else is licensed under the [Apache 2 License](../LICENSE) -------------------------------------------------------------------------------- /src/parser/SqlBaseLexer.js: -------------------------------------------------------------------------------- 1 | // Generated from SqlBase.g4 by ANTLR 4.7.2 2 | // jshint ignore: start 3 | var antlr4 = require('antlr4/index') 4 | 5 | var serializedATN = ['\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964', 6 | '\u0002\u0098\u0524\b\u0001\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004', 7 | '\u0004\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t', 8 | '\u0007\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004', 9 | '\f\t\f\u0004\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010', 10 | '\t\u0010\u0004\u0011\t\u0011\u0004\u0012\t\u0012\u0004\u0013\t\u0013', 11 | '\u0004\u0014\t\u0014\u0004\u0015\t\u0015\u0004\u0016\t\u0016\u0004\u0017', 12 | '\t\u0017\u0004\u0018\t\u0018\u0004\u0019\t\u0019\u0004\u001a\t\u001a', 13 | '\u0004\u001b\t\u001b\u0004\u001c\t\u001c\u0004\u001d\t\u001d\u0004\u001e', 14 | '\t\u001e\u0004\u001f\t\u001f\u0004 \t \u0004!\t!\u0004"\t"\u0004#', 15 | "\t#\u0004$\t$\u0004%\t%\u0004&\t&\u0004\'\t\'\u0004(\t(\u0004)\t)\u0004", 16 | '*\t*\u0004+\t+\u0004,\t,\u0004-\t-\u0004.\t.\u0004/\t/\u00040\t0\u0004', 17 | '1\t1\u00042\t2\u00043\t3\u00044\t4\u00045\t5\u00046\t6\u00047\t7\u0004', 18 | '8\t8\u00049\t9\u0004:\t:\u0004;\t;\u0004<\t<\u0004=\t=\u0004>\t>\u0004', 19 | '?\t?\u0004@\t@\u0004A\tA\u0004B\tB\u0004C\tC\u0004D\tD\u0004E\tE\u0004', 20 | 'F\tF\u0004G\tG\u0004H\tH\u0004I\tI\u0004J\tJ\u0004K\tK\u0004L\tL\u0004', 21 | 'M\tM\u0004N\tN\u0004O\tO\u0004P\tP\u0004Q\tQ\u0004R\tR\u0004S\tS\u0004', 22 | 'T\tT\u0004U\tU\u0004V\tV\u0004W\tW\u0004X\tX\u0004Y\tY\u0004Z\tZ\u0004', 23 | '[\t[\u0004\\\t\\\u0004]\t]\u0004^\t^\u0004_\t_\u0004`\t`\u0004a\ta\u0004', 24 | 'b\tb\u0004c\tc\u0004d\td\u0004e\te\u0004f\tf\u0004g\tg\u0004h\th\u0004', 25 | 'i\ti\u0004j\tj\u0004k\tk\u0004l\tl\u0004m\tm\u0004n\tn\u0004o\to\u0004', 26 | 'p\tp\u0004q\tq\u0004r\tr\u0004s\ts\u0004t\tt\u0004u\tu\u0004v\tv\u0004', 27 | 'w\tw\u0004x\tx\u0004y\ty\u0004z\tz\u0004{\t{\u0004|\t|\u0004}\t}\u0004', 28 | '~\t~\u0004\u007f\t\u007f\u0004\u0080\t\u0080\u0004\u0081\t\u0081\u0004', 29 | '\u0082\t\u0082\u0004\u0083\t\u0083\u0004\u0084\t\u0084\u0004\u0085\t', 30 | '\u0085\u0004\u0086\t\u0086\u0004\u0087\t\u0087\u0004\u0088\t\u0088\u0004', 31 | '\u0089\t\u0089\u0004\u008a\t\u008a\u0004\u008b\t\u008b\u0004\u008c\t', 32 | '\u008c\u0004\u008d\t\u008d\u0004\u008e\t\u008e\u0004\u008f\t\u008f\u0004', 33 | '\u0090\t\u0090\u0004\u0091\t\u0091\u0004\u0092\t\u0092\u0004\u0093\t', 34 | '\u0093\u0004\u0094\t\u0094\u0004\u0095\t\u0095\u0004\u0096\t\u0096\u0004', 35 | '\u0097\t\u0097\u0004\u0098\t\u0098\u0004\u0099\t\u0099\u0004\u009a\t', 36 | '\u009a\u0003\u0002\u0003\u0002\u0003\u0003\u0003\u0003\u0003\u0004\u0003', 37 | '\u0004\u0003\u0005\u0003\u0005\u0003\u0006\u0003\u0006\u0003\u0007\u0003', 38 | '\u0007\u0003\b\u0003\b\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003', 39 | '\n\u0003\n\u0003\n\u0003\n\u0003\n\u0003\n\u0003\n\u0003\n\u0003\u000b', 40 | '\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b', 41 | '\u0003\f\u0003\f\u0003\f\u0003\f\u0003\f\u0003\r\u0003\r\u0003\r\u0003', 42 | '\u000e\u0003\u000e\u0003\u000e\u0003\u000e\u0003\u000e\u0003\u000e\u0003', 43 | '\u000e\u0003\u000e\u0003\u000e\u0003\u000f\u0003\u000f\u0003\u000f\u0003', 44 | '\u000f\u0003\u000f\u0003\u000f\u0003\u0010\u0003\u0010\u0003\u0010\u0003', 45 | '\u0010\u0003\u0010\u0003\u0010\u0003\u0010\u0003\u0011\u0003\u0011\u0003', 46 | '\u0011\u0003\u0011\u0003\u0011\u0003\u0011\u0003\u0011\u0003\u0012\u0003', 47 | '\u0012\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0013\u0003', 48 | '\u0013\u0003\u0013\u0003\u0014\u0003\u0014\u0003\u0014\u0003\u0014\u0003', 49 | '\u0014\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003\u0015\u0003', 50 | '\u0015\u0003\u0015\u0003\u0015\u0003\u0016\u0003\u0016\u0003\u0016\u0003', 51 | '\u0017\u0003\u0017\u0003\u0017\u0003\u0018\u0003\u0018\u0003\u0018\u0003', 52 | '\u0018\u0003\u0019\u0003\u0019\u0003\u0019\u0003\u001a\u0003\u001a\u0003', 53 | '\u001a\u0003\u001a\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003', 54 | '\u001b\u0003\u001b\u0003\u001b\u0003\u001c\u0003\u001c\u0003\u001c\u0003', 55 | '\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001d\u0003', 56 | '\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001e\u0003\u001e\u0003', 57 | '\u001e\u0003\u001f\u0003\u001f\u0003\u001f\u0003\u001f\u0003\u001f\u0003', 58 | ' \u0003 \u0003 \u0003 \u0003 \u0003!\u0003!\u0003!\u0003!\u0003!\u0003', 59 | '!\u0003"\u0003"\u0003"\u0003"\u0003"\u0003"\u0003"\u0003"\u0003', 60 | '#\u0003#\u0003#\u0003#\u0003#\u0003$\u0003$\u0003$\u0003$\u0003$\u0003', 61 | '%\u0003%\u0003%\u0003%\u0003%\u0003%\u0003%\u0003%\u0003%\u0003%\u0003', 62 | "&\u0003&\u0003&\u0003&\u0003&\u0003&\u0003&\u0003&\u0003&\u0003\'\u0003", 63 | "\'\u0003\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0003(\u0003(\u0003", 64 | '(\u0003)\u0003)\u0003)\u0003)\u0003*\u0003*\u0003*\u0003*\u0003*\u0003', 65 | '+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003,\u0003,\u0003,\u0003', 66 | ',\u0003,\u0003,\u0003,\u0003-\u0003-\u0003-\u0003-\u0003-\u0003-\u0003', 67 | '-\u0003-\u0003-\u0003-\u0003-\u0003-\u0003.\u0003.\u0003.\u0003.\u0003', 68 | '.\u0003.\u0003/\u0003/\u0003/\u0003/\u0003/\u0003/\u0003/\u00030\u0003', 69 | '0\u00030\u00030\u00030\u00031\u00031\u00031\u00031\u00031\u00031\u0003', 70 | '2\u00032\u00032\u00032\u00032\u00032\u00032\u00032\u00033\u00033\u0003', 71 | '3\u00033\u00033\u00033\u00033\u00033\u00034\u00034\u00034\u00034\u0003', 72 | '4\u00034\u00034\u00034\u00034\u00034\u00034\u00034\u00034\u00035\u0003', 73 | '5\u00035\u00035\u00035\u00036\u00036\u00036\u00036\u00036\u00036\u0003', 74 | '6\u00036\u00036\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003', 75 | '7\u00038\u00038\u00038\u00038\u00038\u00039\u00039\u00039\u00039\u0003', 76 | '9\u00039\u00039\u00039\u0003:\u0003:\u0003:\u0003:\u0003:\u0003;\u0003', 77 | ';\u0003;\u0003;\u0003;\u0003<\u0003<\u0003<\u0003<\u0003<\u0003=\u0003', 78 | '=\u0003=\u0003=\u0003=\u0003>\u0003>\u0003>\u0003>\u0003?\u0003?\u0003', 79 | '?\u0003?\u0003?\u0003@\u0003@\u0003@\u0003@\u0003@\u0003A\u0003A\u0003', 80 | 'A\u0003A\u0003A\u0003A\u0003B\u0003B\u0003B\u0003B\u0003B\u0003B\u0003', 81 | 'C\u0003C\u0003C\u0003C\u0003C\u0003D\u0003D\u0003D\u0003D\u0003D\u0003', 82 | 'D\u0003E\u0003E\u0003E\u0003F\u0003F\u0003F\u0003F\u0003F\u0003F\u0003', 83 | 'F\u0003F\u0003F\u0003F\u0003G\u0003G\u0003G\u0003G\u0003G\u0003G\u0003', 84 | 'G\u0003H\u0003H\u0003H\u0003H\u0003H\u0003I\u0003I\u0003I\u0003I\u0003', 85 | 'I\u0003I\u0003I\u0003J\u0003J\u0003J\u0003J\u0003J\u0003J\u0003J\u0003', 86 | 'K\u0003K\u0003K\u0003K\u0003K\u0003K\u0003L\u0003L\u0003L\u0003L\u0003', 87 | 'L\u0003L\u0003M\u0003M\u0003M\u0003M\u0003M\u0003M\u0003M\u0003N\u0003', 88 | 'N\u0003N\u0003N\u0003N\u0003N\u0003N\u0003N\u0003O\u0003O\u0003O\u0003', 89 | 'O\u0003O\u0003O\u0003O\u0003P\u0003P\u0003P\u0003P\u0003P\u0003P\u0003', 90 | 'P\u0003Q\u0003Q\u0003Q\u0003Q\u0003Q\u0003R\u0003R\u0003R\u0003R\u0003', 91 | 'R\u0003R\u0003R\u0003R\u0003R\u0003S\u0003S\u0003S\u0003S\u0003S\u0003', 92 | 'S\u0003S\u0003S\u0003S\u0003T\u0003T\u0003T\u0003T\u0003T\u0003T\u0003', 93 | 'U\u0003U\u0003U\u0003U\u0003U\u0003U\u0003U\u0003U\u0003V\u0003V\u0003', 94 | 'V\u0003V\u0003V\u0003V\u0003V\u0003V\u0003W\u0003W\u0003W\u0003W\u0003', 95 | 'W\u0003X\u0003X\u0003X\u0003X\u0003X\u0003X\u0003Y\u0003Y\u0003Y\u0003', 96 | 'Y\u0003Y\u0003Z\u0003Z\u0003Z\u0003Z\u0003Z\u0003[\u0003[\u0003[\u0003', 97 | '[\u0003[\u0003\\\u0003\\\u0003\\\u0003\\\u0003\\\u0003\\\u0003\\\u0003', 98 | ']\u0003]\u0003]\u0003]\u0003]\u0003]\u0003]\u0003^\u0003^\u0003^\u0003', 99 | '^\u0003^\u0003^\u0003_\u0003_\u0003_\u0003_\u0003_\u0003_\u0003_\u0003', 100 | '_\u0003`\u0003`\u0003`\u0003`\u0003`\u0003`\u0003`\u0003`\u0003`\u0003', 101 | '`\u0003a\u0003a\u0003a\u0003a\u0003a\u0003b\u0003b\u0003b\u0003b\u0003', 102 | 'b\u0003b\u0003b\u0003b\u0003c\u0003c\u0003c\u0003c\u0003c\u0003c\u0003', 103 | 'c\u0003d\u0003d\u0003d\u0003d\u0003d\u0003d\u0003d\u0003d\u0003d\u0003', 104 | 'd\u0003d\u0003e\u0003e\u0003e\u0003e\u0003e\u0003e\u0003e\u0003e\u0003', 105 | 'e\u0003e\u0003f\u0003f\u0003f\u0003f\u0003f\u0003f\u0003f\u0003f\u0003', 106 | 'f\u0003g\u0003g\u0003g\u0003g\u0003g\u0003h\u0003h\u0003h\u0003i\u0003', 107 | 'i\u0003i\u0003i\u0003i\u0003i\u0003i\u0003j\u0003j\u0003j\u0003j\u0003', 108 | 'j\u0003j\u0003k\u0003k\u0003k\u0003k\u0003l\u0003l\u0003l\u0003l\u0003', 109 | 'm\u0003m\u0003m\u0003m\u0003m\u0003m\u0003n\u0003n\u0003n\u0003n\u0003', 110 | 'n\u0003n\u0003n\u0003n\u0003o\u0003o\u0003o\u0003o\u0003o\u0003o\u0003', 111 | 'o\u0003p\u0003p\u0003p\u0003p\u0003p\u0003p\u0003p\u0003q\u0003q\u0003', 112 | 'q\u0003q\u0003q\u0003q\u0003q\u0003q\u0003r\u0003r\u0003r\u0003r\u0003', 113 | 'r\u0003r\u0003r\u0003r\u0003r\u0003r\u0003r\u0003s\u0003s\u0003s\u0003', 114 | 's\u0003s\u0003s\u0003s\u0003s\u0003s\u0003s\u0003t\u0003t\u0003t\u0003', 115 | 't\u0003t\u0003t\u0003u\u0003u\u0003u\u0003u\u0003v\u0003v\u0003v\u0003', 116 | 'v\u0003v\u0003v\u0003v\u0003w\u0003w\u0003w\u0003w\u0003w\u0003w\u0003', 117 | 'w\u0003w\u0003x\u0003x\u0003x\u0003x\u0003y\u0003y\u0003y\u0003y\u0003', 118 | 'y\u0003y\u0003y\u0003y\u0003y\u0003y\u0003z\u0003z\u0003z\u0003z\u0003', 119 | 'z\u0003z\u0003z\u0003z\u0003z\u0003z\u0003z\u0003{\u0003{\u0003{\u0003', 120 | '{\u0003{\u0003|\u0003|\u0003|\u0003|\u0003|\u0003|\u0003|\u0003}\u0003', 121 | '}\u0003}\u0003~\u0003~\u0003\u007f\u0003\u007f\u0003\u007f\u0003\u007f', 122 | '\u0005\u007f\u043b\n\u007f\u0003\u0080\u0003\u0080\u0003\u0081\u0003', 123 | '\u0081\u0003\u0081\u0003\u0082\u0003\u0082\u0003\u0083\u0003\u0083\u0003', 124 | '\u0083\u0003\u0084\u0003\u0084\u0003\u0085\u0003\u0085\u0003\u0086\u0003', 125 | '\u0086\u0003\u0087\u0003\u0087\u0003\u0088\u0003\u0088\u0003\u0089\u0003', 126 | '\u0089\u0003\u0089\u0003\u008a\u0003\u008a\u0003\u008a\u0003\u008b\u0003', 127 | '\u008b\u0003\u008b\u0003\u008b\u0007\u008b\u045b\n\u008b\f\u008b\u000e', 128 | '\u008b\u045e\u000b\u008b\u0003\u008b\u0003\u008b\u0003\u008c\u0006\u008c', 129 | '\u0463\n\u008c\r\u008c\u000e\u008c\u0464\u0003\u008d\u0006\u008d\u0468', 130 | '\n\u008d\r\u008d\u000e\u008d\u0469\u0003\u008d\u0003\u008d\u0007\u008d', 131 | '\u046e\n\u008d\f\u008d\u000e\u008d\u0471\u000b\u008d\u0003\u008d\u0003', 132 | '\u008d\u0006\u008d\u0475\n\u008d\r\u008d\u000e\u008d\u0476\u0003\u008d', 133 | '\u0006\u008d\u047a\n\u008d\r\u008d\u000e\u008d\u047b\u0003\u008d\u0003', 134 | '\u008d\u0007\u008d\u0480\n\u008d\f\u008d\u000e\u008d\u0483\u000b\u008d', 135 | '\u0005\u008d\u0485\n\u008d\u0003\u008d\u0003\u008d\u0003\u008d\u0003', 136 | '\u008d\u0006\u008d\u048b\n\u008d\r\u008d\u000e\u008d\u048c\u0003\u008d', 137 | '\u0003\u008d\u0005\u008d\u0491\n\u008d\u0003\u008e\u0003\u008e\u0005', 138 | '\u008e\u0495\n\u008e\u0003\u008e\u0003\u008e\u0003\u008e\u0007\u008e', 139 | '\u049a\n\u008e\f\u008e\u000e\u008e\u049d\u000b\u008e\u0003\u008f\u0003', 140 | '\u008f\u0003\u008f\u0003\u008f\u0006\u008f\u04a3\n\u008f\r\u008f\u000e', 141 | '\u008f\u04a4\u0003\u0090\u0003\u0090\u0003\u0090\u0003\u0090\u0007\u0090', 142 | '\u04ab\n\u0090\f\u0090\u000e\u0090\u04ae\u000b\u0090\u0003\u0090\u0003', 143 | '\u0090\u0003\u0091\u0003\u0091\u0003\u0091\u0003\u0091\u0007\u0091\u04b6', 144 | '\n\u0091\f\u0091\u000e\u0091\u04b9\u000b\u0091\u0003\u0091\u0003\u0091', 145 | '\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092', 146 | '\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092', 147 | '\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092', 148 | '\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0092\u0003\u0093', 149 | '\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093', 150 | '\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093', 151 | '\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093', 152 | '\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0093', 153 | '\u0003\u0093\u0003\u0093\u0003\u0093\u0003\u0094\u0003\u0094\u0005\u0094', 154 | '\u04f2\n\u0094\u0003\u0094\u0006\u0094\u04f5\n\u0094\r\u0094\u000e\u0094', 155 | '\u04f6\u0003\u0095\u0003\u0095\u0003\u0096\u0003\u0096\u0003\u0097\u0003', 156 | '\u0097\u0003\u0097\u0003\u0097\u0007\u0097\u0501\n\u0097\f\u0097\u000e', 157 | '\u0097\u0504\u000b\u0097\u0003\u0097\u0005\u0097\u0507\n\u0097\u0003', 158 | '\u0097\u0005\u0097\u050a\n\u0097\u0003\u0097\u0003\u0097\u0003\u0098', 159 | '\u0003\u0098\u0003\u0098\u0003\u0098\u0007\u0098\u0512\n\u0098\f\u0098', 160 | '\u000e\u0098\u0515\u000b\u0098\u0003\u0098\u0003\u0098\u0003\u0098\u0003', 161 | '\u0098\u0003\u0098\u0003\u0099\u0006\u0099\u051d\n\u0099\r\u0099\u000e', 162 | '\u0099\u051e\u0003\u0099\u0003\u0099\u0003\u009a\u0003\u009a\u0003\u0513', 163 | '\u0002\u009b\u0003\u0003\u0005\u0004\u0007\u0005\t\u0006\u000b\u0007', 164 | '\r\b\u000f\t\u0011\n\u0013\u000b\u0015\f\u0017\r\u0019\u000e\u001b\u000f', 165 | "\u001d\u0010\u001f\u0011!\u0012#\u0013%\u0014\'\u0015)\u0016+\u0017", 166 | '-\u0018/\u00191\u001a3\u001b5\u001c7\u001d9\u001e;\u001f= ?!A"C#E$', 167 | "G%I&K\'M(O)Q*S+U,W-Y.[/]0_1a2c3e4g5i6k7m8o9q:s;u{?}@\u007fA\u0081", 168 | 'B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095', 169 | 'L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9', 170 | 'V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd', 171 | '`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1', 172 | 'j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00ddp\u00dfq\u00e1r\u00e3s\u00e5', 173 | 't\u00e7u\u00e9v\u00ebw\u00edx\u00efy\u00f1z\u00f3{\u00f5|\u00f7}\u00f9', 174 | '~\u00fb\u007f\u00fd\u0080\u00ff\u0081\u0101\u0082\u0103\u0083\u0105', 175 | '\u0084\u0107\u0085\u0109\u0086\u010b\u0087\u010d\u0088\u010f\u0089\u0111', 176 | '\u008a\u0113\u008b\u0115\u008c\u0117\u008d\u0119\u008e\u011b\u008f\u011d', 177 | '\u0090\u011f\u0091\u0121\u0092\u0123\u0093\u0125\u0094\u0127\u0002\u0129', 178 | '\u0002\u012b\u0002\u012d\u0095\u012f\u0096\u0131\u0097\u0133\u0098\u0003', 179 | '\u0002\u000b\u0003\u0002))\u0004\u0002BBaa\u0003\u0002$$\u0003\u0002', 180 | 'bb\u0004\u0002--//\u0003\u00022;\u0004\u0002C\\c|\u0004\u0002\f\f\u000f', 181 | '\u000f\u0005\u0002\u000b\f\u000f\u000f""\u0002\u0540\u0002\u0003\u0003', 182 | '\u0002\u0002\u0002\u0002\u0005\u0003\u0002\u0002\u0002\u0002\u0007\u0003', 183 | '\u0002\u0002\u0002\u0002\t\u0003\u0002\u0002\u0002\u0002\u000b\u0003', 184 | '\u0002\u0002\u0002\u0002\r\u0003\u0002\u0002\u0002\u0002\u000f\u0003', 185 | '\u0002\u0002\u0002\u0002\u0011\u0003\u0002\u0002\u0002\u0002\u0013\u0003', 186 | '\u0002\u0002\u0002\u0002\u0015\u0003\u0002\u0002\u0002\u0002\u0017\u0003', 187 | '\u0002\u0002\u0002\u0002\u0019\u0003\u0002\u0002\u0002\u0002\u001b\u0003', 188 | '\u0002\u0002\u0002\u0002\u001d\u0003\u0002\u0002\u0002\u0002\u001f\u0003', 189 | '\u0002\u0002\u0002\u0002!\u0003\u0002\u0002\u0002\u0002#\u0003\u0002', 190 | "\u0002\u0002\u0002%\u0003\u0002\u0002\u0002\u0002\'\u0003\u0002\u0002", 191 | '\u0002\u0002)\u0003\u0002\u0002\u0002\u0002+\u0003\u0002\u0002\u0002', 192 | '\u0002-\u0003\u0002\u0002\u0002\u0002/\u0003\u0002\u0002\u0002\u0002', 193 | '1\u0003\u0002\u0002\u0002\u00023\u0003\u0002\u0002\u0002\u00025\u0003', 194 | '\u0002\u0002\u0002\u00027\u0003\u0002\u0002\u0002\u00029\u0003\u0002', 195 | '\u0002\u0002\u0002;\u0003\u0002\u0002\u0002\u0002=\u0003\u0002\u0002', 196 | '\u0002\u0002?\u0003\u0002\u0002\u0002\u0002A\u0003\u0002\u0002\u0002', 197 | '\u0002C\u0003\u0002\u0002\u0002\u0002E\u0003\u0002\u0002\u0002\u0002', 198 | 'G\u0003\u0002\u0002\u0002\u0002I\u0003\u0002\u0002\u0002\u0002K\u0003', 199 | '\u0002\u0002\u0002\u0002M\u0003\u0002\u0002\u0002\u0002O\u0003\u0002', 200 | '\u0002\u0002\u0002Q\u0003\u0002\u0002\u0002\u0002S\u0003\u0002\u0002', 201 | '\u0002\u0002U\u0003\u0002\u0002\u0002\u0002W\u0003\u0002\u0002\u0002', 202 | '\u0002Y\u0003\u0002\u0002\u0002\u0002[\u0003\u0002\u0002\u0002\u0002', 203 | ']\u0003\u0002\u0002\u0002\u0002_\u0003\u0002\u0002\u0002\u0002a\u0003', 204 | '\u0002\u0002\u0002\u0002c\u0003\u0002\u0002\u0002\u0002e\u0003\u0002', 205 | '\u0002\u0002\u0002g\u0003\u0002\u0002\u0002\u0002i\u0003\u0002\u0002', 206 | '\u0002\u0002k\u0003\u0002\u0002\u0002\u0002m\u0003\u0002\u0002\u0002', 207 | '\u0002o\u0003\u0002\u0002\u0002\u0002q\u0003\u0002\u0002\u0002\u0002', 208 | 's\u0003\u0002\u0002\u0002\u0002u\u0003\u0002\u0002\u0002\u0002w\u0003', 209 | '\u0002\u0002\u0002\u0002y\u0003\u0002\u0002\u0002\u0002{\u0003\u0002', 210 | '\u0002\u0002\u0002}\u0003\u0002\u0002\u0002\u0002\u007f\u0003\u0002', 211 | '\u0002\u0002\u0002\u0081\u0003\u0002\u0002\u0002\u0002\u0083\u0003\u0002', 212 | '\u0002\u0002\u0002\u0085\u0003\u0002\u0002\u0002\u0002\u0087\u0003\u0002', 213 | '\u0002\u0002\u0002\u0089\u0003\u0002\u0002\u0002\u0002\u008b\u0003\u0002', 214 | '\u0002\u0002\u0002\u008d\u0003\u0002\u0002\u0002\u0002\u008f\u0003\u0002', 215 | '\u0002\u0002\u0002\u0091\u0003\u0002\u0002\u0002\u0002\u0093\u0003\u0002', 216 | '\u0002\u0002\u0002\u0095\u0003\u0002\u0002\u0002\u0002\u0097\u0003\u0002', 217 | '\u0002\u0002\u0002\u0099\u0003\u0002\u0002\u0002\u0002\u009b\u0003\u0002', 218 | '\u0002\u0002\u0002\u009d\u0003\u0002\u0002\u0002\u0002\u009f\u0003\u0002', 219 | '\u0002\u0002\u0002\u00a1\u0003\u0002\u0002\u0002\u0002\u00a3\u0003\u0002', 220 | '\u0002\u0002\u0002\u00a5\u0003\u0002\u0002\u0002\u0002\u00a7\u0003\u0002', 221 | '\u0002\u0002\u0002\u00a9\u0003\u0002\u0002\u0002\u0002\u00ab\u0003\u0002', 222 | '\u0002\u0002\u0002\u00ad\u0003\u0002\u0002\u0002\u0002\u00af\u0003\u0002', 223 | '\u0002\u0002\u0002\u00b1\u0003\u0002\u0002\u0002\u0002\u00b3\u0003\u0002', 224 | '\u0002\u0002\u0002\u00b5\u0003\u0002\u0002\u0002\u0002\u00b7\u0003\u0002', 225 | '\u0002\u0002\u0002\u00b9\u0003\u0002\u0002\u0002\u0002\u00bb\u0003\u0002', 226 | '\u0002\u0002\u0002\u00bd\u0003\u0002\u0002\u0002\u0002\u00bf\u0003\u0002', 227 | '\u0002\u0002\u0002\u00c1\u0003\u0002\u0002\u0002\u0002\u00c3\u0003\u0002', 228 | '\u0002\u0002\u0002\u00c5\u0003\u0002\u0002\u0002\u0002\u00c7\u0003\u0002', 229 | '\u0002\u0002\u0002\u00c9\u0003\u0002\u0002\u0002\u0002\u00cb\u0003\u0002', 230 | '\u0002\u0002\u0002\u00cd\u0003\u0002\u0002\u0002\u0002\u00cf\u0003\u0002', 231 | '\u0002\u0002\u0002\u00d1\u0003\u0002\u0002\u0002\u0002\u00d3\u0003\u0002', 232 | '\u0002\u0002\u0002\u00d5\u0003\u0002\u0002\u0002\u0002\u00d7\u0003\u0002', 233 | '\u0002\u0002\u0002\u00d9\u0003\u0002\u0002\u0002\u0002\u00db\u0003\u0002', 234 | '\u0002\u0002\u0002\u00dd\u0003\u0002\u0002\u0002\u0002\u00df\u0003\u0002', 235 | '\u0002\u0002\u0002\u00e1\u0003\u0002\u0002\u0002\u0002\u00e3\u0003\u0002', 236 | '\u0002\u0002\u0002\u00e5\u0003\u0002\u0002\u0002\u0002\u00e7\u0003\u0002', 237 | '\u0002\u0002\u0002\u00e9\u0003\u0002\u0002\u0002\u0002\u00eb\u0003\u0002', 238 | '\u0002\u0002\u0002\u00ed\u0003\u0002\u0002\u0002\u0002\u00ef\u0003\u0002', 239 | '\u0002\u0002\u0002\u00f1\u0003\u0002\u0002\u0002\u0002\u00f3\u0003\u0002', 240 | '\u0002\u0002\u0002\u00f5\u0003\u0002\u0002\u0002\u0002\u00f7\u0003\u0002', 241 | '\u0002\u0002\u0002\u00f9\u0003\u0002\u0002\u0002\u0002\u00fb\u0003\u0002', 242 | '\u0002\u0002\u0002\u00fd\u0003\u0002\u0002\u0002\u0002\u00ff\u0003\u0002', 243 | '\u0002\u0002\u0002\u0101\u0003\u0002\u0002\u0002\u0002\u0103\u0003\u0002', 244 | '\u0002\u0002\u0002\u0105\u0003\u0002\u0002\u0002\u0002\u0107\u0003\u0002', 245 | '\u0002\u0002\u0002\u0109\u0003\u0002\u0002\u0002\u0002\u010b\u0003\u0002', 246 | '\u0002\u0002\u0002\u010d\u0003\u0002\u0002\u0002\u0002\u010f\u0003\u0002', 247 | '\u0002\u0002\u0002\u0111\u0003\u0002\u0002\u0002\u0002\u0113\u0003\u0002', 248 | '\u0002\u0002\u0002\u0115\u0003\u0002\u0002\u0002\u0002\u0117\u0003\u0002', 249 | '\u0002\u0002\u0002\u0119\u0003\u0002\u0002\u0002\u0002\u011b\u0003\u0002', 250 | '\u0002\u0002\u0002\u011d\u0003\u0002\u0002\u0002\u0002\u011f\u0003\u0002', 251 | '\u0002\u0002\u0002\u0121\u0003\u0002\u0002\u0002\u0002\u0123\u0003\u0002', 252 | '\u0002\u0002\u0002\u0125\u0003\u0002\u0002\u0002\u0002\u012d\u0003\u0002', 253 | '\u0002\u0002\u0002\u012f\u0003\u0002\u0002\u0002\u0002\u0131\u0003\u0002', 254 | '\u0002\u0002\u0002\u0133\u0003\u0002\u0002\u0002\u0003\u0135\u0003\u0002', 255 | '\u0002\u0002\u0005\u0137\u0003\u0002\u0002\u0002\u0007\u0139\u0003\u0002', 256 | '\u0002\u0002\t\u013b\u0003\u0002\u0002\u0002\u000b\u013d\u0003\u0002', 257 | '\u0002\u0002\r\u013f\u0003\u0002\u0002\u0002\u000f\u0141\u0003\u0002', 258 | '\u0002\u0002\u0011\u0143\u0003\u0002\u0002\u0002\u0013\u0148\u0003\u0002', 259 | '\u0002\u0002\u0015\u0150\u0003\u0002\u0002\u0002\u0017\u0157\u0003\u0002', 260 | '\u0002\u0002\u0019\u015c\u0003\u0002\u0002\u0002\u001b\u015f\u0003\u0002', 261 | '\u0002\u0002\u001d\u0168\u0003\u0002\u0002\u0002\u001f\u016e\u0003\u0002', 262 | '\u0002\u0002!\u0175\u0003\u0002\u0002\u0002#\u017c\u0003\u0002\u0002', 263 | "\u0002%\u0182\u0003\u0002\u0002\u0002\'\u0185\u0003\u0002\u0002\u0002", 264 | ')\u018c\u0003\u0002\u0002\u0002+\u0192\u0003\u0002\u0002\u0002-\u0195', 265 | '\u0003\u0002\u0002\u0002/\u0198\u0003\u0002\u0002\u00021\u019c\u0003', 266 | '\u0002\u0002\u00023\u019f\u0003\u0002\u0002\u00025\u01a3\u0003\u0002', 267 | '\u0002\u00027\u01aa\u0003\u0002\u0002\u00029\u01b2\u0003\u0002\u0002', 268 | '\u0002;\u01b7\u0003\u0002\u0002\u0002=\u01ba\u0003\u0002\u0002\u0002', 269 | '?\u01bf\u0003\u0002\u0002\u0002A\u01c4\u0003\u0002\u0002\u0002C\u01ca', 270 | '\u0003\u0002\u0002\u0002E\u01d2\u0003\u0002\u0002\u0002G\u01d7\u0003', 271 | '\u0002\u0002\u0002I\u01dc\u0003\u0002\u0002\u0002K\u01e6\u0003\u0002', 272 | '\u0002\u0002M\u01ef\u0003\u0002\u0002\u0002O\u01f4\u0003\u0002\u0002', 273 | '\u0002Q\u01fa\u0003\u0002\u0002\u0002S\u01fe\u0003\u0002\u0002\u0002', 274 | 'U\u0203\u0003\u0002\u0002\u0002W\u020a\u0003\u0002\u0002\u0002Y\u0211', 275 | '\u0003\u0002\u0002\u0002[\u021d\u0003\u0002\u0002\u0002]\u0223\u0003', 276 | '\u0002\u0002\u0002_\u022a\u0003\u0002\u0002\u0002a\u022f\u0003\u0002', 277 | '\u0002\u0002c\u0235\u0003\u0002\u0002\u0002e\u023d\u0003\u0002\u0002', 278 | '\u0002g\u0245\u0003\u0002\u0002\u0002i\u0252\u0003\u0002\u0002\u0002', 279 | 'k\u0257\u0003\u0002\u0002\u0002m\u0260\u0003\u0002\u0002\u0002o\u0268', 280 | '\u0003\u0002\u0002\u0002q\u026d\u0003\u0002\u0002\u0002s\u0275\u0003', 281 | '\u0002\u0002\u0002u\u027a\u0003\u0002\u0002\u0002w\u027f\u0003\u0002', 282 | '\u0002\u0002y\u0284\u0003\u0002\u0002\u0002{\u0289\u0003\u0002\u0002', 283 | '\u0002}\u028d\u0003\u0002\u0002\u0002\u007f\u0292\u0003\u0002\u0002', 284 | '\u0002\u0081\u0297\u0003\u0002\u0002\u0002\u0083\u029d\u0003\u0002\u0002', 285 | '\u0002\u0085\u02a3\u0003\u0002\u0002\u0002\u0087\u02a8\u0003\u0002\u0002', 286 | '\u0002\u0089\u02ae\u0003\u0002\u0002\u0002\u008b\u02b1\u0003\u0002\u0002', 287 | '\u0002\u008d\u02bb\u0003\u0002\u0002\u0002\u008f\u02c2\u0003\u0002\u0002', 288 | '\u0002\u0091\u02c7\u0003\u0002\u0002\u0002\u0093\u02ce\u0003\u0002\u0002', 289 | '\u0002\u0095\u02d5\u0003\u0002\u0002\u0002\u0097\u02db\u0003\u0002\u0002', 290 | '\u0002\u0099\u02e1\u0003\u0002\u0002\u0002\u009b\u02e8\u0003\u0002\u0002', 291 | '\u0002\u009d\u02f0\u0003\u0002\u0002\u0002\u009f\u02f7\u0003\u0002\u0002', 292 | '\u0002\u00a1\u02fe\u0003\u0002\u0002\u0002\u00a3\u0303\u0003\u0002\u0002', 293 | '\u0002\u00a5\u030c\u0003\u0002\u0002\u0002\u00a7\u0315\u0003\u0002\u0002', 294 | '\u0002\u00a9\u031b\u0003\u0002\u0002\u0002\u00ab\u0323\u0003\u0002\u0002', 295 | '\u0002\u00ad\u032b\u0003\u0002\u0002\u0002\u00af\u0330\u0003\u0002\u0002', 296 | '\u0002\u00b1\u0336\u0003\u0002\u0002\u0002\u00b3\u033b\u0003\u0002\u0002', 297 | '\u0002\u00b5\u0340\u0003\u0002\u0002\u0002\u00b7\u0345\u0003\u0002\u0002', 298 | '\u0002\u00b9\u034c\u0003\u0002\u0002\u0002\u00bb\u0353\u0003\u0002\u0002', 299 | '\u0002\u00bd\u0359\u0003\u0002\u0002\u0002\u00bf\u0361\u0003\u0002\u0002', 300 | '\u0002\u00c1\u036b\u0003\u0002\u0002\u0002\u00c3\u0370\u0003\u0002\u0002', 301 | '\u0002\u00c5\u0378\u0003\u0002\u0002\u0002\u00c7\u037f\u0003\u0002\u0002', 302 | '\u0002\u00c9\u038a\u0003\u0002\u0002\u0002\u00cb\u0394\u0003\u0002\u0002', 303 | '\u0002\u00cd\u039d\u0003\u0002\u0002\u0002\u00cf\u03a2\u0003\u0002\u0002', 304 | '\u0002\u00d1\u03a5\u0003\u0002\u0002\u0002\u00d3\u03ac\u0003\u0002\u0002', 305 | '\u0002\u00d5\u03b2\u0003\u0002\u0002\u0002\u00d7\u03b6\u0003\u0002\u0002', 306 | '\u0002\u00d9\u03ba\u0003\u0002\u0002\u0002\u00db\u03c0\u0003\u0002\u0002', 307 | '\u0002\u00dd\u03c8\u0003\u0002\u0002\u0002\u00df\u03cf\u0003\u0002\u0002', 308 | '\u0002\u00e1\u03d6\u0003\u0002\u0002\u0002\u00e3\u03de\u0003\u0002\u0002', 309 | '\u0002\u00e5\u03e9\u0003\u0002\u0002\u0002\u00e7\u03f3\u0003\u0002\u0002', 310 | '\u0002\u00e9\u03f9\u0003\u0002\u0002\u0002\u00eb\u03fd\u0003\u0002\u0002', 311 | '\u0002\u00ed\u0404\u0003\u0002\u0002\u0002\u00ef\u040c\u0003\u0002\u0002', 312 | '\u0002\u00f1\u0410\u0003\u0002\u0002\u0002\u00f3\u041a\u0003\u0002\u0002', 313 | '\u0002\u00f5\u0425\u0003\u0002\u0002\u0002\u00f7\u042a\u0003\u0002\u0002', 314 | '\u0002\u00f9\u0431\u0003\u0002\u0002\u0002\u00fb\u0434\u0003\u0002\u0002', 315 | '\u0002\u00fd\u043a\u0003\u0002\u0002\u0002\u00ff\u043c\u0003\u0002\u0002', 316 | '\u0002\u0101\u043e\u0003\u0002\u0002\u0002\u0103\u0441\u0003\u0002\u0002', 317 | '\u0002\u0105\u0443\u0003\u0002\u0002\u0002\u0107\u0446\u0003\u0002\u0002', 318 | '\u0002\u0109\u0448\u0003\u0002\u0002\u0002\u010b\u044a\u0003\u0002\u0002', 319 | '\u0002\u010d\u044c\u0003\u0002\u0002\u0002\u010f\u044e\u0003\u0002\u0002', 320 | '\u0002\u0111\u0450\u0003\u0002\u0002\u0002\u0113\u0453\u0003\u0002\u0002', 321 | '\u0002\u0115\u0456\u0003\u0002\u0002\u0002\u0117\u0462\u0003\u0002\u0002', 322 | '\u0002\u0119\u0490\u0003\u0002\u0002\u0002\u011b\u0494\u0003\u0002\u0002', 323 | '\u0002\u011d\u049e\u0003\u0002\u0002\u0002\u011f\u04a6\u0003\u0002\u0002', 324 | '\u0002\u0121\u04b1\u0003\u0002\u0002\u0002\u0123\u04bc\u0003\u0002\u0002', 325 | '\u0002\u0125\u04d3\u0003\u0002\u0002\u0002\u0127\u04ef\u0003\u0002\u0002', 326 | '\u0002\u0129\u04f8\u0003\u0002\u0002\u0002\u012b\u04fa\u0003\u0002\u0002', 327 | '\u0002\u012d\u04fc\u0003\u0002\u0002\u0002\u012f\u050d\u0003\u0002\u0002', 328 | '\u0002\u0131\u051c\u0003\u0002\u0002\u0002\u0133\u0522\u0003\u0002\u0002', 329 | '\u0002\u0135\u0136\u0007=\u0002\u0002\u0136\u0004\u0003\u0002\u0002', 330 | '\u0002\u0137\u0138\u0007.\u0002\u0002\u0138\u0006\u0003\u0002\u0002', 331 | '\u0002\u0139\u013a\u0007*\u0002\u0002\u013a\b\u0003\u0002\u0002\u0002', 332 | '\u013b\u013c\u0007+\u0002\u0002\u013c\n\u0003\u0002\u0002\u0002\u013d', 333 | '\u013e\u00070\u0002\u0002\u013e\f\u0003\u0002\u0002\u0002\u013f\u0140', 334 | '\u0007]\u0002\u0002\u0140\u000e\u0003\u0002\u0002\u0002\u0141\u0142', 335 | '\u0007_\u0002\u0002\u0142\u0010\u0003\u0002\u0002\u0002\u0143\u0144', 336 | '\u0007G\u0002\u0002\u0144\u0145\u0007O\u0002\u0002\u0145\u0146\u0007', 337 | 'K\u0002\u0002\u0146\u0147\u0007V\u0002\u0002\u0147\u0012\u0003\u0002', 338 | '\u0002\u0002\u0148\u0149\u0007E\u0002\u0002\u0149\u014a\u0007J\u0002', 339 | '\u0002\u014a\u014b\u0007C\u0002\u0002\u014b\u014c\u0007P\u0002\u0002', 340 | '\u014c\u014d\u0007I\u0002\u0002\u014d\u014e\u0007G\u0002\u0002\u014e', 341 | '\u014f\u0007U\u0002\u0002\u014f\u0014\u0003\u0002\u0002\u0002\u0150', 342 | '\u0151\u0007U\u0002\u0002\u0151\u0152\u0007G\u0002\u0002\u0152\u0153', 343 | '\u0007N\u0002\u0002\u0153\u0154\u0007G\u0002\u0002\u0154\u0155\u0007', 344 | 'E\u0002\u0002\u0155\u0156\u0007V\u0002\u0002\u0156\u0016\u0003\u0002', 345 | '\u0002\u0002\u0157\u0158\u0007H\u0002\u0002\u0158\u0159\u0007T\u0002', 346 | '\u0002\u0159\u015a\u0007Q\u0002\u0002\u015a\u015b\u0007O\u0002\u0002', 347 | '\u015b\u0018\u0003\u0002\u0002\u0002\u015c\u015d\u0007C\u0002\u0002', 348 | '\u015d\u015e\u0007U\u0002\u0002\u015e\u001a\u0003\u0002\u0002\u0002', 349 | '\u015f\u0160\u0007F\u0002\u0002\u0160\u0161\u0007K\u0002\u0002\u0161', 350 | '\u0162\u0007U\u0002\u0002\u0162\u0163\u0007V\u0002\u0002\u0163\u0164', 351 | '\u0007K\u0002\u0002\u0164\u0165\u0007P\u0002\u0002\u0165\u0166\u0007', 352 | 'E\u0002\u0002\u0166\u0167\u0007V\u0002\u0002\u0167\u001c\u0003\u0002', 353 | '\u0002\u0002\u0168\u0169\u0007Y\u0002\u0002\u0169\u016a\u0007J\u0002', 354 | '\u0002\u016a\u016b\u0007G\u0002\u0002\u016b\u016c\u0007T\u0002\u0002', 355 | '\u016c\u016d\u0007G\u0002\u0002\u016d\u001e\u0003\u0002\u0002\u0002', 356 | '\u016e\u016f\u0007Y\u0002\u0002\u016f\u0170\u0007K\u0002\u0002\u0170', 357 | '\u0171\u0007V\u0002\u0002\u0171\u0172\u0007J\u0002\u0002\u0172\u0173', 358 | '\u0007K\u0002\u0002\u0173\u0174\u0007P\u0002\u0002\u0174 \u0003\u0002', 359 | '\u0002\u0002\u0175\u0176\u0007Y\u0002\u0002\u0176\u0177\u0007K\u0002', 360 | '\u0002\u0177\u0178\u0007P\u0002\u0002\u0178\u0179\u0007F\u0002\u0002', 361 | '\u0179\u017a\u0007Q\u0002\u0002\u017a\u017b\u0007Y\u0002\u0002\u017b', 362 | '"\u0003\u0002\u0002\u0002\u017c\u017d\u0007I\u0002\u0002\u017d\u017e', 363 | '\u0007T\u0002\u0002\u017e\u017f\u0007Q\u0002\u0002\u017f\u0180\u0007', 364 | 'W\u0002\u0002\u0180\u0181\u0007R\u0002\u0002\u0181$\u0003\u0002\u0002', 365 | '\u0002\u0182\u0183\u0007D\u0002\u0002\u0183\u0184\u0007[\u0002\u0002', 366 | '\u0184&\u0003\u0002\u0002\u0002\u0185\u0186\u0007J\u0002\u0002\u0186', 367 | '\u0187\u0007C\u0002\u0002\u0187\u0188\u0007X\u0002\u0002\u0188\u0189', 368 | '\u0007K\u0002\u0002\u0189\u018a\u0007P\u0002\u0002\u018a\u018b\u0007', 369 | 'I\u0002\u0002\u018b(\u0003\u0002\u0002\u0002\u018c\u018d\u0007N\u0002', 370 | '\u0002\u018d\u018e\u0007K\u0002\u0002\u018e\u018f\u0007O\u0002\u0002', 371 | '\u018f\u0190\u0007K\u0002\u0002\u0190\u0191\u0007V\u0002\u0002\u0191', 372 | '*\u0003\u0002\u0002\u0002\u0192\u0193\u0007C\u0002\u0002\u0193\u0194', 373 | '\u0007V\u0002\u0002\u0194,\u0003\u0002\u0002\u0002\u0195\u0196\u0007', 374 | 'Q\u0002\u0002\u0196\u0197\u0007T\u0002\u0002\u0197.\u0003\u0002\u0002', 375 | '\u0002\u0198\u0199\u0007C\u0002\u0002\u0199\u019a\u0007P\u0002\u0002', 376 | '\u019a\u019b\u0007F\u0002\u0002\u019b0\u0003\u0002\u0002\u0002\u019c', 377 | '\u019d\u0007K\u0002\u0002\u019d\u019e\u0007P\u0002\u0002\u019e2\u0003', 378 | '\u0002\u0002\u0002\u019f\u01a0\u0007P\u0002\u0002\u01a0\u01a1\u0007', 379 | 'Q\u0002\u0002\u01a1\u01a2\u0007V\u0002\u0002\u01a24\u0003\u0002\u0002', 380 | '\u0002\u01a3\u01a4\u0007G\u0002\u0002\u01a4\u01a5\u0007Z\u0002\u0002', 381 | '\u01a5\u01a6\u0007K\u0002\u0002\u01a6\u01a7\u0007U\u0002\u0002\u01a7', 382 | '\u01a8\u0007V\u0002\u0002\u01a8\u01a9\u0007U\u0002\u0002\u01a96\u0003', 383 | '\u0002\u0002\u0002\u01aa\u01ab\u0007D\u0002\u0002\u01ab\u01ac\u0007', 384 | 'G\u0002\u0002\u01ac\u01ad\u0007V\u0002\u0002\u01ad\u01ae\u0007Y\u0002', 385 | '\u0002\u01ae\u01af\u0007G\u0002\u0002\u01af\u01b0\u0007G\u0002\u0002', 386 | '\u01b0\u01b1\u0007P\u0002\u0002\u01b18\u0003\u0002\u0002\u0002\u01b2', 387 | '\u01b3\u0007N\u0002\u0002\u01b3\u01b4\u0007K\u0002\u0002\u01b4\u01b5', 388 | '\u0007M\u0002\u0002\u01b5\u01b6\u0007G\u0002\u0002\u01b6:\u0003\u0002', 389 | '\u0002\u0002\u01b7\u01b8\u0007K\u0002\u0002\u01b8\u01b9\u0007U\u0002', 390 | '\u0002\u01b9<\u0003\u0002\u0002\u0002\u01ba\u01bb\u0007P\u0002\u0002', 391 | '\u01bb\u01bc\u0007W\u0002\u0002\u01bc\u01bd\u0007N\u0002\u0002\u01bd', 392 | '\u01be\u0007N\u0002\u0002\u01be>\u0003\u0002\u0002\u0002\u01bf\u01c0', 393 | '\u0007V\u0002\u0002\u01c0\u01c1\u0007T\u0002\u0002\u01c1\u01c2\u0007', 394 | 'W\u0002\u0002\u01c2\u01c3\u0007G\u0002\u0002\u01c3@\u0003\u0002\u0002', 395 | '\u0002\u01c4\u01c5\u0007H\u0002\u0002\u01c5\u01c6\u0007C\u0002\u0002', 396 | '\u01c6\u01c7\u0007N\u0002\u0002\u01c7\u01c8\u0007U\u0002\u0002\u01c8', 397 | '\u01c9\u0007G\u0002\u0002\u01c9B\u0003\u0002\u0002\u0002\u01ca\u01cb', 398 | '\u0007K\u0002\u0002\u01cb\u01cc\u0007P\u0002\u0002\u01cc\u01cd\u0007', 399 | 'V\u0002\u0002\u01cd\u01ce\u0007G\u0002\u0002\u01ce\u01cf\u0007I\u0002', 400 | '\u0002\u01cf\u01d0\u0007G\u0002\u0002\u01d0\u01d1\u0007T\u0002\u0002', 401 | '\u01d1D\u0003\u0002\u0002\u0002\u01d2\u01d3\u0007F\u0002\u0002\u01d3', 402 | '\u01d4\u0007C\u0002\u0002\u01d4\u01d5\u0007V\u0002\u0002\u01d5\u01d6', 403 | '\u0007G\u0002\u0002\u01d6F\u0003\u0002\u0002\u0002\u01d7\u01d8\u0007', 404 | 'V\u0002\u0002\u01d8\u01d9\u0007K\u0002\u0002\u01d9\u01da\u0007O\u0002', 405 | '\u0002\u01da\u01db\u0007G\u0002\u0002\u01dbH\u0003\u0002\u0002\u0002', 406 | '\u01dc\u01dd\u0007V\u0002\u0002\u01dd\u01de\u0007K\u0002\u0002\u01de', 407 | '\u01df\u0007O\u0002\u0002\u01df\u01e0\u0007G\u0002\u0002\u01e0\u01e1', 408 | '\u0007U\u0002\u0002\u01e1\u01e2\u0007V\u0002\u0002\u01e2\u01e3\u0007', 409 | 'C\u0002\u0002\u01e3\u01e4\u0007O\u0002\u0002\u01e4\u01e5\u0007R\u0002', 410 | '\u0002\u01e5J\u0003\u0002\u0002\u0002\u01e6\u01e7\u0007K\u0002\u0002', 411 | '\u01e7\u01e8\u0007P\u0002\u0002\u01e8\u01e9\u0007V\u0002\u0002\u01e9', 412 | '\u01ea\u0007G\u0002\u0002\u01ea\u01eb\u0007T\u0002\u0002\u01eb\u01ec', 413 | '\u0007X\u0002\u0002\u01ec\u01ed\u0007C\u0002\u0002\u01ed\u01ee\u0007', 414 | 'N\u0002\u0002\u01eeL\u0003\u0002\u0002\u0002\u01ef\u01f0\u0007[\u0002', 415 | '\u0002\u01f0\u01f1\u0007G\u0002\u0002\u01f1\u01f2\u0007C\u0002\u0002', 416 | '\u01f2\u01f3\u0007T\u0002\u0002\u01f3N\u0003\u0002\u0002\u0002\u01f4', 417 | '\u01f5\u0007O\u0002\u0002\u01f5\u01f6\u0007Q\u0002\u0002\u01f6\u01f7', 418 | '\u0007P\u0002\u0002\u01f7\u01f8\u0007V\u0002\u0002\u01f8\u01f9\u0007', 419 | 'J\u0002\u0002\u01f9P\u0003\u0002\u0002\u0002\u01fa\u01fb\u0007F\u0002', 420 | '\u0002\u01fb\u01fc\u0007C\u0002\u0002\u01fc\u01fd\u0007[\u0002\u0002', 421 | '\u01fdR\u0003\u0002\u0002\u0002\u01fe\u01ff\u0007J\u0002\u0002\u01ff', 422 | '\u0200\u0007Q\u0002\u0002\u0200\u0201\u0007W\u0002\u0002\u0201\u0202', 423 | '\u0007T\u0002\u0002\u0202T\u0003\u0002\u0002\u0002\u0203\u0204\u0007', 424 | 'O\u0002\u0002\u0204\u0205\u0007K\u0002\u0002\u0205\u0206\u0007P\u0002', 425 | '\u0002\u0206\u0207\u0007W\u0002\u0002\u0207\u0208\u0007V\u0002\u0002', 426 | '\u0208\u0209\u0007G\u0002\u0002\u0209V\u0003\u0002\u0002\u0002\u020a', 427 | '\u020b\u0007U\u0002\u0002\u020b\u020c\u0007G\u0002\u0002\u020c\u020d', 428 | '\u0007E\u0002\u0002\u020d\u020e\u0007Q\u0002\u0002\u020e\u020f\u0007', 429 | 'P\u0002\u0002\u020f\u0210\u0007F\u0002\u0002\u0210X\u0003\u0002\u0002', 430 | '\u0002\u0211\u0212\u0007O\u0002\u0002\u0212\u0213\u0007K\u0002\u0002', 431 | '\u0213\u0214\u0007N\u0002\u0002\u0214\u0215\u0007N\u0002\u0002\u0215', 432 | '\u0216\u0007K\u0002\u0002\u0216\u0217\u0007U\u0002\u0002\u0217\u0218', 433 | '\u0007G\u0002\u0002\u0218\u0219\u0007E\u0002\u0002\u0219\u021a\u0007', 434 | 'Q\u0002\u0002\u021a\u021b\u0007P\u0002\u0002\u021b\u021c\u0007F\u0002', 435 | '\u0002\u021cZ\u0003\u0002\u0002\u0002\u021d\u021e\u0007[\u0002\u0002', 436 | '\u021e\u021f\u0007G\u0002\u0002\u021f\u0220\u0007C\u0002\u0002\u0220', 437 | '\u0221\u0007T\u0002\u0002\u0221\u0222\u0007U\u0002\u0002\u0222\\\u0003', 438 | '\u0002\u0002\u0002\u0223\u0224\u0007O\u0002\u0002\u0224\u0225\u0007', 439 | 'Q\u0002\u0002\u0225\u0226\u0007P\u0002\u0002\u0226\u0227\u0007V\u0002', 440 | '\u0002\u0227\u0228\u0007J\u0002\u0002\u0228\u0229\u0007U\u0002\u0002', 441 | '\u0229^\u0003\u0002\u0002\u0002\u022a\u022b\u0007F\u0002\u0002\u022b', 442 | '\u022c\u0007C\u0002\u0002\u022c\u022d\u0007[\u0002\u0002\u022d\u022e', 443 | '\u0007U\u0002\u0002\u022e`\u0003\u0002\u0002\u0002\u022f\u0230\u0007', 444 | 'J\u0002\u0002\u0230\u0231\u0007Q\u0002\u0002\u0231\u0232\u0007W\u0002', 445 | '\u0002\u0232\u0233\u0007T\u0002\u0002\u0233\u0234\u0007U\u0002\u0002', 446 | '\u0234b\u0003\u0002\u0002\u0002\u0235\u0236\u0007O\u0002\u0002\u0236', 447 | '\u0237\u0007K\u0002\u0002\u0237\u0238\u0007P\u0002\u0002\u0238\u0239', 448 | '\u0007W\u0002\u0002\u0239\u023a\u0007V\u0002\u0002\u023a\u023b\u0007', 449 | 'G\u0002\u0002\u023b\u023c\u0007U\u0002\u0002\u023cd\u0003\u0002\u0002', 450 | '\u0002\u023d\u023e\u0007U\u0002\u0002\u023e\u023f\u0007G\u0002\u0002', 451 | '\u023f\u0240\u0007E\u0002\u0002\u0240\u0241\u0007Q\u0002\u0002\u0241', 452 | '\u0242\u0007P\u0002\u0002\u0242\u0243\u0007F\u0002\u0002\u0243\u0244', 453 | '\u0007U\u0002\u0002\u0244f\u0003\u0002\u0002\u0002\u0245\u0246\u0007', 454 | 'O\u0002\u0002\u0246\u0247\u0007K\u0002\u0002\u0247\u0248\u0007N\u0002', 455 | '\u0002\u0248\u0249\u0007N\u0002\u0002\u0249\u024a\u0007K\u0002\u0002', 456 | '\u024a\u024b\u0007U\u0002\u0002\u024b\u024c\u0007G\u0002\u0002\u024c', 457 | '\u024d\u0007E\u0002\u0002\u024d\u024e\u0007Q\u0002\u0002\u024e\u024f', 458 | '\u0007P\u0002\u0002\u024f\u0250\u0007F\u0002\u0002\u0250\u0251\u0007', 459 | 'U\u0002\u0002\u0251h\u0003\u0002\u0002\u0002\u0252\u0253\u0007\\\u0002', 460 | '\u0002\u0253\u0254\u0007Q\u0002\u0002\u0254\u0255\u0007P\u0002\u0002', 461 | '\u0255\u0256\u0007G\u0002\u0002\u0256j\u0003\u0002\u0002\u0002\u0257', 462 | '\u0258\u0007V\u0002\u0002\u0258\u0259\u0007W\u0002\u0002\u0259\u025a', 463 | '\u0007O\u0002\u0002\u025a\u025b\u0007D\u0002\u0002\u025b\u025c\u0007', 464 | 'N\u0002\u0002\u025c\u025d\u0007K\u0002\u0002\u025d\u025e\u0007P\u0002', 465 | '\u0002\u025e\u025f\u0007I\u0002\u0002\u025fl\u0003\u0002\u0002\u0002', 466 | '\u0260\u0261\u0007J\u0002\u0002\u0261\u0262\u0007Q\u0002\u0002\u0262', 467 | '\u0263\u0007R\u0002\u0002\u0263\u0264\u0007R\u0002\u0002\u0264\u0265', 468 | '\u0007K\u0002\u0002\u0265\u0266\u0007P\u0002\u0002\u0266\u0267\u0007', 469 | 'I\u0002\u0002\u0267n\u0003\u0002\u0002\u0002\u0268\u0269\u0007U\u0002', 470 | '\u0002\u0269\u026a\u0007K\u0002\u0002\u026a\u026b\u0007\\\u0002\u0002', 471 | '\u026b\u026c\u0007G\u0002\u0002\u026cp\u0003\u0002\u0002\u0002\u026d', 472 | '\u026e\u0007C\u0002\u0002\u026e\u026f\u0007F\u0002\u0002\u026f\u0270', 473 | '\u0007X\u0002\u0002\u0270\u0271\u0007C\u0002\u0002\u0271\u0272\u0007', 474 | 'P\u0002\u0002\u0272\u0273\u0007E\u0002\u0002\u0273\u0274\u0007G\u0002', 475 | '\u0002\u0274r\u0003\u0002\u0002\u0002\u0275\u0276\u0007E\u0002\u0002', 476 | '\u0276\u0277\u0007C\u0002\u0002\u0277\u0278\u0007U\u0002\u0002\u0278', 477 | '\u0279\u0007G\u0002\u0002\u0279t\u0003\u0002\u0002\u0002\u027a\u027b', 478 | '\u0007Y\u0002\u0002\u027b\u027c\u0007J\u0002\u0002\u027c\u027d\u0007', 479 | 'G\u0002\u0002\u027d\u027e\u0007P\u0002\u0002\u027ev\u0003\u0002\u0002', 480 | '\u0002\u027f\u0280\u0007V\u0002\u0002\u0280\u0281\u0007J\u0002\u0002', 481 | '\u0281\u0282\u0007G\u0002\u0002\u0282\u0283\u0007P\u0002\u0002\u0283', 482 | 'x\u0003\u0002\u0002\u0002\u0284\u0285\u0007G\u0002\u0002\u0285\u0286', 483 | '\u0007N\u0002\u0002\u0286\u0287\u0007U\u0002\u0002\u0287\u0288\u0007', 484 | 'G\u0002\u0002\u0288z\u0003\u0002\u0002\u0002\u0289\u028a\u0007G\u0002', 485 | '\u0002\u028a\u028b\u0007P\u0002\u0002\u028b\u028c\u0007F\u0002\u0002', 486 | '\u028c|\u0003\u0002\u0002\u0002\u028d\u028e\u0007L\u0002\u0002\u028e', 487 | '\u028f\u0007Q\u0002\u0002\u028f\u0290\u0007K\u0002\u0002\u0290\u0291', 488 | '\u0007P\u0002\u0002\u0291~\u0003\u0002\u0002\u0002\u0292\u0293\u0007', 489 | 'H\u0002\u0002\u0293\u0294\u0007W\u0002\u0002\u0294\u0295\u0007N\u0002', 490 | '\u0002\u0295\u0296\u0007N\u0002\u0002\u0296\u0080\u0003\u0002\u0002', 491 | '\u0002\u0297\u0298\u0007Q\u0002\u0002\u0298\u0299\u0007W\u0002\u0002', 492 | '\u0299\u029a\u0007V\u0002\u0002\u029a\u029b\u0007G\u0002\u0002\u029b', 493 | '\u029c\u0007T\u0002\u0002\u029c\u0082\u0003\u0002\u0002\u0002\u029d', 494 | '\u029e\u0007K\u0002\u0002\u029e\u029f\u0007P\u0002\u0002\u029f\u02a0', 495 | '\u0007P\u0002\u0002\u02a0\u02a1\u0007G\u0002\u0002\u02a1\u02a2\u0007', 496 | 'T\u0002\u0002\u02a2\u0084\u0003\u0002\u0002\u0002\u02a3\u02a4\u0007', 497 | 'N\u0002\u0002\u02a4\u02a5\u0007G\u0002\u0002\u02a5\u02a6\u0007H\u0002', 498 | '\u0002\u02a6\u02a7\u0007V\u0002\u0002\u02a7\u0086\u0003\u0002\u0002', 499 | '\u0002\u02a8\u02a9\u0007T\u0002\u0002\u02a9\u02aa\u0007K\u0002\u0002', 500 | '\u02aa\u02ab\u0007I\u0002\u0002\u02ab\u02ac\u0007J\u0002\u0002\u02ac', 501 | '\u02ad\u0007V\u0002\u0002\u02ad\u0088\u0003\u0002\u0002\u0002\u02ae', 502 | '\u02af\u0007Q\u0002\u0002\u02af\u02b0\u0007P\u0002\u0002\u02b0\u008a', 503 | '\u0003\u0002\u0002\u0002\u02b1\u02b2\u0007R\u0002\u0002\u02b2\u02b3', 504 | '\u0007C\u0002\u0002\u02b3\u02b4\u0007T\u0002\u0002\u02b4\u02b5\u0007', 505 | 'V\u0002\u0002\u02b5\u02b6\u0007K\u0002\u0002\u02b6\u02b7\u0007V\u0002', 506 | '\u0002\u02b7\u02b8\u0007K\u0002\u0002\u02b8\u02b9\u0007Q\u0002\u0002', 507 | '\u02b9\u02ba\u0007P\u0002\u0002\u02ba\u008c\u0003\u0002\u0002\u0002', 508 | '\u02bb\u02bc\u0007U\u0002\u0002\u02bc\u02bd\u0007V\u0002\u0002\u02bd', 509 | '\u02be\u0007T\u0002\u0002\u02be\u02bf\u0007W\u0002\u0002\u02bf\u02c0', 510 | '\u0007E\u0002\u0002\u02c0\u02c1\u0007V\u0002\u0002\u02c1\u008e\u0003', 511 | '\u0002\u0002\u0002\u02c2\u02c3\u0007Y\u0002\u0002\u02c3\u02c4\u0007', 512 | 'K\u0002\u0002\u02c4\u02c5\u0007V\u0002\u0002\u02c5\u02c6\u0007J\u0002', 513 | '\u0002\u02c6\u0090\u0003\u0002\u0002\u0002\u02c7\u02c8\u0007X\u0002', 514 | '\u0002\u02c8\u02c9\u0007C\u0002\u0002\u02c9\u02ca\u0007N\u0002\u0002', 515 | '\u02ca\u02cb\u0007W\u0002\u0002\u02cb\u02cc\u0007G\u0002\u0002\u02cc', 516 | '\u02cd\u0007U\u0002\u0002\u02cd\u0092\u0003\u0002\u0002\u0002\u02ce', 517 | '\u02cf\u0007E\u0002\u0002\u02cf\u02d0\u0007T\u0002\u0002\u02d0\u02d1', 518 | '\u0007G\u0002\u0002\u02d1\u02d2\u0007C\u0002\u0002\u02d2\u02d3\u0007', 519 | 'V\u0002\u0002\u02d3\u02d4\u0007G\u0002\u0002\u02d4\u0094\u0003\u0002', 520 | '\u0002\u0002\u02d5\u02d6\u0007V\u0002\u0002\u02d6\u02d7\u0007C\u0002', 521 | '\u0002\u02d7\u02d8\u0007D\u0002\u0002\u02d8\u02d9\u0007N\u0002\u0002', 522 | '\u02d9\u02da\u0007G\u0002\u0002\u02da\u0096\u0003\u0002\u0002\u0002', 523 | '\u02db\u02dc\u0007V\u0002\u0002\u02dc\u02dd\u0007Q\u0002\u0002\u02dd', 524 | '\u02de\u0007R\u0002\u0002\u02de\u02df\u0007K\u0002\u0002\u02df\u02e0', 525 | '\u0007E\u0002\u0002\u02e0\u0098\u0003\u0002\u0002\u0002\u02e1\u02e2', 526 | '\u0007U\u0002\u0002\u02e2\u02e3\u0007V\u0002\u0002\u02e3\u02e4\u0007', 527 | 'T\u0002\u0002\u02e4\u02e5\u0007G\u0002\u0002\u02e5\u02e6\u0007C\u0002', 528 | '\u0002\u02e6\u02e7\u0007O\u0002\u0002\u02e7\u009a\u0003\u0002\u0002', 529 | '\u0002\u02e8\u02e9\u0007U\u0002\u0002\u02e9\u02ea\u0007V\u0002\u0002', 530 | '\u02ea\u02eb\u0007T\u0002\u0002\u02eb\u02ec\u0007G\u0002\u0002\u02ec', 531 | '\u02ed\u0007C\u0002\u0002\u02ed\u02ee\u0007O\u0002\u0002\u02ee\u02ef', 532 | '\u0007U\u0002\u0002\u02ef\u009c\u0003\u0002\u0002\u0002\u02f0\u02f1', 533 | '\u0007K\u0002\u0002\u02f1\u02f2\u0007P\u0002\u0002\u02f2\u02f3\u0007', 534 | 'U\u0002\u0002\u02f3\u02f4\u0007G\u0002\u0002\u02f4\u02f5\u0007T\u0002', 535 | '\u0002\u02f5\u02f6\u0007V\u0002\u0002\u02f6\u009e\u0003\u0002\u0002', 536 | '\u0002\u02f7\u02f8\u0007F\u0002\u0002\u02f8\u02f9\u0007G\u0002\u0002', 537 | '\u02f9\u02fa\u0007N\u0002\u0002\u02fa\u02fb\u0007G\u0002\u0002\u02fb', 538 | '\u02fc\u0007V\u0002\u0002\u02fc\u02fd\u0007G\u0002\u0002\u02fd\u00a0', 539 | '\u0003\u0002\u0002\u0002\u02fe\u02ff\u0007K\u0002\u0002\u02ff\u0300', 540 | '\u0007P\u0002\u0002\u0300\u0301\u0007V\u0002\u0002\u0301\u0302\u0007', 541 | 'Q\u0002\u0002\u0302\u00a2\u0003\u0002\u0002\u0002\u0303\u0304\u0007', 542 | 'F\u0002\u0002\u0304\u0305\u0007G\u0002\u0002\u0305\u0306\u0007U\u0002', 543 | '\u0002\u0306\u0307\u0007E\u0002\u0002\u0307\u0308\u0007T\u0002\u0002', 544 | '\u0308\u0309\u0007K\u0002\u0002\u0309\u030a\u0007D\u0002\u0002\u030a', 545 | '\u030b\u0007G\u0002\u0002\u030b\u00a4\u0003\u0002\u0002\u0002\u030c', 546 | '\u030d\u0007G\u0002\u0002\u030d\u030e\u0007Z\u0002\u0002\u030e\u030f', 547 | '\u0007V\u0002\u0002\u030f\u0310\u0007G\u0002\u0002\u0310\u0311\u0007', 548 | 'P\u0002\u0002\u0311\u0312\u0007F\u0002\u0002\u0312\u0313\u0007G\u0002', 549 | '\u0002\u0313\u0314\u0007F\u0002\u0002\u0314\u00a6\u0003\u0002\u0002', 550 | '\u0002\u0315\u0316\u0007R\u0002\u0002\u0316\u0317\u0007T\u0002\u0002', 551 | '\u0317\u0318\u0007K\u0002\u0002\u0318\u0319\u0007P\u0002\u0002\u0319', 552 | '\u031a\u0007V\u0002\u0002\u031a\u00a8\u0003\u0002\u0002\u0002\u031b', 553 | '\u031c\u0007G\u0002\u0002\u031c\u031d\u0007Z\u0002\u0002\u031d\u031e', 554 | '\u0007R\u0002\u0002\u031e\u031f\u0007N\u0002\u0002\u031f\u0320\u0007', 555 | 'C\u0002\u0002\u0320\u0321\u0007K\u0002\u0002\u0321\u0322\u0007P\u0002', 556 | '\u0002\u0322\u00aa\u0003\u0002\u0002\u0002\u0323\u0324\u0007C\u0002', 557 | '\u0002\u0324\u0325\u0007P\u0002\u0002\u0325\u0326\u0007C\u0002\u0002', 558 | '\u0326\u0327\u0007N\u0002\u0002\u0327\u0328\u0007[\u0002\u0002\u0328', 559 | '\u0329\u0007\\\u0002\u0002\u0329\u032a\u0007G\u0002\u0002\u032a\u00ac', 560 | '\u0003\u0002\u0002\u0002\u032b\u032c\u0007V\u0002\u0002\u032c\u032d', 561 | '\u0007[\u0002\u0002\u032d\u032e\u0007R\u0002\u0002\u032e\u032f\u0007', 562 | 'G\u0002\u0002\u032f\u00ae\u0003\u0002\u0002\u0002\u0330\u0331\u0007', 563 | 'V\u0002\u0002\u0331\u0332\u0007[\u0002\u0002\u0332\u0333\u0007R\u0002', 564 | '\u0002\u0333\u0334\u0007G\u0002\u0002\u0334\u0335\u0007U\u0002\u0002', 565 | '\u0335\u00b0\u0003\u0002\u0002\u0002\u0336\u0337\u0007E\u0002\u0002', 566 | '\u0337\u0338\u0007C\u0002\u0002\u0338\u0339\u0007U\u0002\u0002\u0339', 567 | '\u033a\u0007V\u0002\u0002\u033a\u00b2\u0003\u0002\u0002\u0002\u033b', 568 | '\u033c\u0007U\u0002\u0002\u033c\u033d\u0007J\u0002\u0002\u033d\u033e', 569 | '\u0007Q\u0002\u0002\u033e\u033f\u0007Y\u0002\u0002\u033f\u00b4\u0003', 570 | '\u0002\u0002\u0002\u0340\u0341\u0007N\u0002\u0002\u0341\u0342\u0007', 571 | 'K\u0002\u0002\u0342\u0343\u0007U\u0002\u0002\u0343\u0344\u0007V\u0002', 572 | '\u0002\u0344\u00b6\u0003\u0002\u0002\u0002\u0345\u0346\u0007V\u0002', 573 | '\u0002\u0346\u0347\u0007C\u0002\u0002\u0347\u0348\u0007D\u0002\u0002', 574 | '\u0348\u0349\u0007N\u0002\u0002\u0349\u034a\u0007G\u0002\u0002\u034a', 575 | '\u034b\u0007U\u0002\u0002\u034b\u00b8\u0003\u0002\u0002\u0002\u034c', 576 | '\u034d\u0007V\u0002\u0002\u034d\u034e\u0007Q\u0002\u0002\u034e\u034f', 577 | '\u0007R\u0002\u0002\u034f\u0350\u0007K\u0002\u0002\u0350\u0351\u0007', 578 | 'E\u0002\u0002\u0351\u0352\u0007U\u0002\u0002\u0352\u00ba\u0003\u0002', 579 | '\u0002\u0002\u0353\u0354\u0007S\u0002\u0002\u0354\u0355\u0007W\u0002', 580 | '\u0002\u0355\u0356\u0007G\u0002\u0002\u0356\u0357\u0007T\u0002\u0002', 581 | '\u0357\u0358\u0007[\u0002\u0002\u0358\u00bc\u0003\u0002\u0002\u0002', 582 | '\u0359\u035a\u0007S\u0002\u0002\u035a\u035b\u0007W\u0002\u0002\u035b', 583 | '\u035c\u0007G\u0002\u0002\u035c\u035d\u0007T\u0002\u0002\u035d\u035e', 584 | '\u0007K\u0002\u0002\u035e\u035f\u0007G\u0002\u0002\u035f\u0360\u0007', 585 | 'U\u0002\u0002\u0360\u00be\u0003\u0002\u0002\u0002\u0361\u0362\u0007', 586 | 'V\u0002\u0002\u0362\u0363\u0007G\u0002\u0002\u0363\u0364\u0007T\u0002', 587 | '\u0002\u0364\u0365\u0007O\u0002\u0002\u0365\u0366\u0007K\u0002\u0002', 588 | '\u0366\u0367\u0007P\u0002\u0002\u0367\u0368\u0007C\u0002\u0002\u0368', 589 | '\u0369\u0007V\u0002\u0002\u0369\u036a\u0007G\u0002\u0002\u036a\u00c0', 590 | '\u0003\u0002\u0002\u0002\u036b\u036c\u0007N\u0002\u0002\u036c\u036d', 591 | '\u0007Q\u0002\u0002\u036d\u036e\u0007C\u0002\u0002\u036e\u036f\u0007', 592 | 'F\u0002\u0002\u036f\u00c2\u0003\u0002\u0002\u0002\u0370\u0371\u0007', 593 | 'E\u0002\u0002\u0371\u0372\u0007Q\u0002\u0002\u0372\u0373\u0007N\u0002', 594 | '\u0002\u0373\u0374\u0007W\u0002\u0002\u0374\u0375\u0007O\u0002\u0002', 595 | '\u0375\u0376\u0007P\u0002\u0002\u0376\u0377\u0007U\u0002\u0002\u0377', 596 | '\u00c4\u0003\u0002\u0002\u0002\u0378\u0379\u0007E\u0002\u0002\u0379', 597 | '\u037a\u0007Q\u0002\u0002\u037a\u037b\u0007N\u0002\u0002\u037b\u037c', 598 | '\u0007W\u0002\u0002\u037c\u037d\u0007O\u0002\u0002\u037d\u037e\u0007', 599 | 'P\u0002\u0002\u037e\u00c6\u0003\u0002\u0002\u0002\u037f\u0380\u0007', 600 | 'R\u0002\u0002\u0380\u0381\u0007C\u0002\u0002\u0381\u0382\u0007T\u0002', 601 | '\u0002\u0382\u0383\u0007V\u0002\u0002\u0383\u0384\u0007K\u0002\u0002', 602 | '\u0384\u0385\u0007V\u0002\u0002\u0385\u0386\u0007K\u0002\u0002\u0386', 603 | '\u0387\u0007Q\u0002\u0002\u0387\u0388\u0007P\u0002\u0002\u0388\u0389', 604 | '\u0007U\u0002\u0002\u0389\u00c8\u0003\u0002\u0002\u0002\u038a\u038b', 605 | '\u0007H\u0002\u0002\u038b\u038c\u0007W\u0002\u0002\u038c\u038d\u0007', 606 | 'P\u0002\u0002\u038d\u038e\u0007E\u0002\u0002\u038e\u038f\u0007V\u0002', 607 | '\u0002\u038f\u0390\u0007K\u0002\u0002\u0390\u0391\u0007Q\u0002\u0002', 608 | '\u0391\u0392\u0007P\u0002\u0002\u0392\u0393\u0007U\u0002\u0002\u0393', 609 | '\u00ca\u0003\u0002\u0002\u0002\u0394\u0395\u0007H\u0002\u0002\u0395', 610 | '\u0396\u0007W\u0002\u0002\u0396\u0397\u0007P\u0002\u0002\u0397\u0398', 611 | '\u0007E\u0002\u0002\u0398\u0399\u0007V\u0002\u0002\u0399\u039a\u0007', 612 | 'K\u0002\u0002\u039a\u039b\u0007Q\u0002\u0002\u039b\u039c\u0007P\u0002', 613 | '\u0002\u039c\u00cc\u0003\u0002\u0002\u0002\u039d\u039e\u0007F\u0002', 614 | '\u0002\u039e\u039f\u0007T\u0002\u0002\u039f\u03a0\u0007Q\u0002\u0002', 615 | '\u03a0\u03a1\u0007R\u0002\u0002\u03a1\u00ce\u0003\u0002\u0002\u0002', 616 | '\u03a2\u03a3\u0007V\u0002\u0002\u03a3\u03a4\u0007Q\u0002\u0002\u03a4', 617 | '\u00d0\u0003\u0002\u0002\u0002\u03a5\u03a6\u0007T\u0002\u0002\u03a6', 618 | '\u03a7\u0007G\u0002\u0002\u03a7\u03a8\u0007P\u0002\u0002\u03a8\u03a9', 619 | '\u0007C\u0002\u0002\u03a9\u03aa\u0007O\u0002\u0002\u03aa\u03ab\u0007', 620 | 'G\u0002\u0002\u03ab\u00d2\u0003\u0002\u0002\u0002\u03ac\u03ad\u0007', 621 | 'C\u0002\u0002\u03ad\u03ae\u0007T\u0002\u0002\u03ae\u03af\u0007T\u0002', 622 | '\u0002\u03af\u03b0\u0007C\u0002\u0002\u03b0\u03b1\u0007[\u0002\u0002', 623 | '\u03b1\u00d4\u0003\u0002\u0002\u0002\u03b2\u03b3\u0007O\u0002\u0002', 624 | '\u03b3\u03b4\u0007C\u0002\u0002\u03b4\u03b5\u0007R\u0002\u0002\u03b5', 625 | '\u00d6\u0003\u0002\u0002\u0002\u03b6\u03b7\u0007U\u0002\u0002\u03b7', 626 | '\u03b8\u0007G\u0002\u0002\u03b8\u03b9\u0007V\u0002\u0002\u03b9\u00d8', 627 | '\u0003\u0002\u0002\u0002\u03ba\u03bb\u0007T\u0002\u0002\u03bb\u03bc', 628 | '\u0007G\u0002\u0002\u03bc\u03bd\u0007U\u0002\u0002\u03bd\u03be\u0007', 629 | 'G\u0002\u0002\u03be\u03bf\u0007V\u0002\u0002\u03bf\u00da\u0003\u0002', 630 | '\u0002\u0002\u03c0\u03c1\u0007U\u0002\u0002\u03c1\u03c2\u0007G\u0002', 631 | '\u0002\u03c2\u03c3\u0007U\u0002\u0002\u03c3\u03c4\u0007U\u0002\u0002', 632 | '\u03c4\u03c5\u0007K\u0002\u0002\u03c5\u03c6\u0007Q\u0002\u0002\u03c6', 633 | '\u03c7\u0007P\u0002\u0002\u03c7\u00dc\u0003\u0002\u0002\u0002\u03c8', 634 | '\u03c9\u0007U\u0002\u0002\u03c9\u03ca\u0007C\u0002\u0002\u03ca\u03cb', 635 | '\u0007O\u0002\u0002\u03cb\u03cc\u0007R\u0002\u0002\u03cc\u03cd\u0007', 636 | 'N\u0002\u0002\u03cd\u03ce\u0007G\u0002\u0002\u03ce\u00de\u0003\u0002', 637 | '\u0002\u0002\u03cf\u03d0\u0007G\u0002\u0002\u03d0\u03d1\u0007Z\u0002', 638 | '\u0002\u03d1\u03d2\u0007R\u0002\u0002\u03d2\u03d3\u0007Q\u0002\u0002', 639 | '\u03d3\u03d4\u0007T\u0002\u0002\u03d4\u03d5\u0007V\u0002\u0002\u03d5', 640 | '\u00e0\u0003\u0002\u0002\u0002\u03d6\u03d7\u0007E\u0002\u0002\u03d7', 641 | '\u03d8\u0007C\u0002\u0002\u03d8\u03d9\u0007V\u0002\u0002\u03d9\u03da', 642 | '\u0007C\u0002\u0002\u03da\u03db\u0007N\u0002\u0002\u03db\u03dc\u0007', 643 | 'Q\u0002\u0002\u03dc\u03dd\u0007I\u0002\u0002\u03dd\u00e2\u0003\u0002', 644 | '\u0002\u0002\u03de\u03df\u0007R\u0002\u0002\u03df\u03e0\u0007T\u0002', 645 | '\u0002\u03e0\u03e1\u0007Q\u0002\u0002\u03e1\u03e2\u0007R\u0002\u0002', 646 | '\u03e2\u03e3\u0007G\u0002\u0002\u03e3\u03e4\u0007T\u0002\u0002\u03e4', 647 | '\u03e5\u0007V\u0002\u0002\u03e5\u03e6\u0007K\u0002\u0002\u03e6\u03e7', 648 | '\u0007G\u0002\u0002\u03e7\u03e8\u0007U\u0002\u0002\u03e8\u00e4\u0003', 649 | '\u0002\u0002\u0002\u03e9\u03ea\u0007D\u0002\u0002\u03ea\u03eb\u0007', 650 | 'G\u0002\u0002\u03eb\u03ec\u0007I\u0002\u0002\u03ec\u03ed\u0007K\u0002', 651 | '\u0002\u03ed\u03ee\u0007P\u0002\u0002\u03ee\u03ef\u0007P\u0002\u0002', 652 | '\u03ef\u03f0\u0007K\u0002\u0002\u03f0\u03f1\u0007P\u0002\u0002\u03f1', 653 | '\u03f2\u0007I\u0002\u0002\u03f2\u00e6\u0003\u0002\u0002\u0002\u03f3', 654 | '\u03f4\u0007W\u0002\u0002\u03f4\u03f5\u0007P\u0002\u0002\u03f5\u03f6', 655 | '\u0007U\u0002\u0002\u03f6\u03f7\u0007G\u0002\u0002\u03f7\u03f8\u0007', 656 | 'V\u0002\u0002\u03f8\u00e8\u0003\u0002\u0002\u0002\u03f9\u03fa\u0007', 657 | 'T\u0002\u0002\u03fa\u03fb\u0007W\u0002\u0002\u03fb\u03fc\u0007P\u0002', 658 | '\u0002\u03fc\u00ea\u0003\u0002\u0002\u0002\u03fd\u03fe\u0007U\u0002', 659 | '\u0002\u03fe\u03ff\u0007E\u0002\u0002\u03ff\u0400\u0007T\u0002\u0002', 660 | '\u0400\u0401\u0007K\u0002\u0002\u0401\u0402\u0007R\u0002\u0002\u0402', 661 | '\u0403\u0007V\u0002\u0002\u0403\u00ec\u0003\u0002\u0002\u0002\u0404', 662 | '\u0405\u0007F\u0002\u0002\u0405\u0406\u0007G\u0002\u0002\u0406\u0407', 663 | '\u0007E\u0002\u0002\u0407\u0408\u0007K\u0002\u0002\u0408\u0409\u0007', 664 | 'O\u0002\u0002\u0409\u040a\u0007C\u0002\u0002\u040a\u040b\u0007N\u0002', 665 | '\u0002\u040b\u00ee\u0003\u0002\u0002\u0002\u040c\u040d\u0007M\u0002', 666 | '\u0002\u040d\u040e\u0007G\u0002\u0002\u040e\u040f\u0007[\u0002\u0002', 667 | '\u040f\u00f0\u0003\u0002\u0002\u0002\u0410\u0411\u0007E\u0002\u0002', 668 | '\u0411\u0412\u0007Q\u0002\u0002\u0412\u0413\u0007P\u0002\u0002\u0413', 669 | '\u0414\u0007P\u0002\u0002\u0414\u0415\u0007G\u0002\u0002\u0415\u0416', 670 | '\u0007E\u0002\u0002\u0416\u0417\u0007V\u0002\u0002\u0417\u0418\u0007', 671 | 'Q\u0002\u0002\u0418\u0419\u0007T\u0002\u0002\u0419\u00f2\u0003\u0002', 672 | '\u0002\u0002\u041a\u041b\u0007E\u0002\u0002\u041b\u041c\u0007Q\u0002', 673 | '\u0002\u041c\u041d\u0007P\u0002\u0002\u041d\u041e\u0007P\u0002\u0002', 674 | '\u041e\u041f\u0007G\u0002\u0002\u041f\u0420\u0007E\u0002\u0002\u0420', 675 | '\u0421\u0007V\u0002\u0002\u0421\u0422\u0007Q\u0002\u0002\u0422\u0423', 676 | '\u0007T\u0002\u0002\u0423\u0424\u0007U\u0002\u0002\u0424\u00f4\u0003', 677 | '\u0002\u0002\u0002\u0425\u0426\u0007U\u0002\u0002\u0426\u0427\u0007', 678 | 'K\u0002\u0002\u0427\u0428\u0007P\u0002\u0002\u0428\u0429\u0007M\u0002', 679 | '\u0002\u0429\u00f6\u0003\u0002\u0002\u0002\u042a\u042b\u0007U\u0002', 680 | '\u0002\u042b\u042c\u0007Q\u0002\u0002\u042c\u042d\u0007W\u0002\u0002', 681 | '\u042d\u042e\u0007T\u0002\u0002\u042e\u042f\u0007E\u0002\u0002\u042f', 682 | '\u0430\u0007G\u0002\u0002\u0430\u00f8\u0003\u0002\u0002\u0002\u0431', 683 | '\u0432\u0007K\u0002\u0002\u0432\u0433\u0007H\u0002\u0002\u0433\u00fa', 684 | '\u0003\u0002\u0002\u0002\u0434\u0435\u0007?\u0002\u0002\u0435\u00fc', 685 | '\u0003\u0002\u0002\u0002\u0436\u0437\u0007>\u0002\u0002\u0437\u043b', 686 | '\u0007@\u0002\u0002\u0438\u0439\u0007#\u0002\u0002\u0439\u043b\u0007', 687 | '?\u0002\u0002\u043a\u0436\u0003\u0002\u0002\u0002\u043a\u0438\u0003', 688 | '\u0002\u0002\u0002\u043b\u00fe\u0003\u0002\u0002\u0002\u043c\u043d\u0007', 689 | '>\u0002\u0002\u043d\u0100\u0003\u0002\u0002\u0002\u043e\u043f\u0007', 690 | '>\u0002\u0002\u043f\u0440\u0007?\u0002\u0002\u0440\u0102\u0003\u0002', 691 | '\u0002\u0002\u0441\u0442\u0007@\u0002\u0002\u0442\u0104\u0003\u0002', 692 | '\u0002\u0002\u0443\u0444\u0007@\u0002\u0002\u0444\u0445\u0007?\u0002', 693 | '\u0002\u0445\u0106\u0003\u0002\u0002\u0002\u0446\u0447\u0007-\u0002', 694 | '\u0002\u0447\u0108\u0003\u0002\u0002\u0002\u0448\u0449\u0007/\u0002', 695 | '\u0002\u0449\u010a\u0003\u0002\u0002\u0002\u044a\u044b\u0007,\u0002', 696 | '\u0002\u044b\u010c\u0003\u0002\u0002\u0002\u044c\u044d\u00071\u0002', 697 | "\u0002\u044d\u010e\u0003\u0002\u0002\u0002\u044e\u044f\u0007\'\u0002", 698 | '\u0002\u044f\u0110\u0003\u0002\u0002\u0002\u0450\u0451\u0007~\u0002', 699 | '\u0002\u0451\u0452\u0007~\u0002\u0002\u0452\u0112\u0003\u0002\u0002', 700 | '\u0002\u0453\u0454\u0007/\u0002\u0002\u0454\u0455\u0007@\u0002\u0002', 701 | '\u0455\u0114\u0003\u0002\u0002\u0002\u0456\u045c\u0007)\u0002\u0002', 702 | '\u0457\u045b\n\u0002\u0002\u0002\u0458\u0459\u0007)\u0002\u0002\u0459', 703 | '\u045b\u0007)\u0002\u0002\u045a\u0457\u0003\u0002\u0002\u0002\u045a', 704 | '\u0458\u0003\u0002\u0002\u0002\u045b\u045e\u0003\u0002\u0002\u0002\u045c', 705 | '\u045a\u0003\u0002\u0002\u0002\u045c\u045d\u0003\u0002\u0002\u0002\u045d', 706 | '\u045f\u0003\u0002\u0002\u0002\u045e\u045c\u0003\u0002\u0002\u0002\u045f', 707 | '\u0460\u0007)\u0002\u0002\u0460\u0116\u0003\u0002\u0002\u0002\u0461', 708 | '\u0463\u0005\u0129\u0095\u0002\u0462\u0461\u0003\u0002\u0002\u0002\u0463', 709 | '\u0464\u0003\u0002\u0002\u0002\u0464\u0462\u0003\u0002\u0002\u0002\u0464', 710 | '\u0465\u0003\u0002\u0002\u0002\u0465\u0118\u0003\u0002\u0002\u0002\u0466', 711 | '\u0468\u0005\u0129\u0095\u0002\u0467\u0466\u0003\u0002\u0002\u0002\u0468', 712 | '\u0469\u0003\u0002\u0002\u0002\u0469\u0467\u0003\u0002\u0002\u0002\u0469', 713 | '\u046a\u0003\u0002\u0002\u0002\u046a\u046b\u0003\u0002\u0002\u0002\u046b', 714 | '\u046f\u00070\u0002\u0002\u046c\u046e\u0005\u0129\u0095\u0002\u046d', 715 | '\u046c\u0003\u0002\u0002\u0002\u046e\u0471\u0003\u0002\u0002\u0002\u046f', 716 | '\u046d\u0003\u0002\u0002\u0002\u046f\u0470\u0003\u0002\u0002\u0002\u0470', 717 | '\u0491\u0003\u0002\u0002\u0002\u0471\u046f\u0003\u0002\u0002\u0002\u0472', 718 | '\u0474\u00070\u0002\u0002\u0473\u0475\u0005\u0129\u0095\u0002\u0474', 719 | '\u0473\u0003\u0002\u0002\u0002\u0475\u0476\u0003\u0002\u0002\u0002\u0476', 720 | '\u0474\u0003\u0002\u0002\u0002\u0476\u0477\u0003\u0002\u0002\u0002\u0477', 721 | '\u0491\u0003\u0002\u0002\u0002\u0478\u047a\u0005\u0129\u0095\u0002\u0479', 722 | '\u0478\u0003\u0002\u0002\u0002\u047a\u047b\u0003\u0002\u0002\u0002\u047b', 723 | '\u0479\u0003\u0002\u0002\u0002\u047b\u047c\u0003\u0002\u0002\u0002\u047c', 724 | '\u0484\u0003\u0002\u0002\u0002\u047d\u0481\u00070\u0002\u0002\u047e', 725 | '\u0480\u0005\u0129\u0095\u0002\u047f\u047e\u0003\u0002\u0002\u0002\u0480', 726 | '\u0483\u0003\u0002\u0002\u0002\u0481\u047f\u0003\u0002\u0002\u0002\u0481', 727 | '\u0482\u0003\u0002\u0002\u0002\u0482\u0485\u0003\u0002\u0002\u0002\u0483', 728 | '\u0481\u0003\u0002\u0002\u0002\u0484\u047d\u0003\u0002\u0002\u0002\u0484', 729 | '\u0485\u0003\u0002\u0002\u0002\u0485\u0486\u0003\u0002\u0002\u0002\u0486', 730 | '\u0487\u0005\u0127\u0094\u0002\u0487\u0491\u0003\u0002\u0002\u0002\u0488', 731 | '\u048a\u00070\u0002\u0002\u0489\u048b\u0005\u0129\u0095\u0002\u048a', 732 | '\u0489\u0003\u0002\u0002\u0002\u048b\u048c\u0003\u0002\u0002\u0002\u048c', 733 | '\u048a\u0003\u0002\u0002\u0002\u048c\u048d\u0003\u0002\u0002\u0002\u048d', 734 | '\u048e\u0003\u0002\u0002\u0002\u048e\u048f\u0005\u0127\u0094\u0002\u048f', 735 | '\u0491\u0003\u0002\u0002\u0002\u0490\u0467\u0003\u0002\u0002\u0002\u0490', 736 | '\u0472\u0003\u0002\u0002\u0002\u0490\u0479\u0003\u0002\u0002\u0002\u0490', 737 | '\u0488\u0003\u0002\u0002\u0002\u0491\u011a\u0003\u0002\u0002\u0002\u0492', 738 | '\u0495\u0005\u012b\u0096\u0002\u0493\u0495\u0007a\u0002\u0002\u0494', 739 | '\u0492\u0003\u0002\u0002\u0002\u0494\u0493\u0003\u0002\u0002\u0002\u0495', 740 | '\u049b\u0003\u0002\u0002\u0002\u0496\u049a\u0005\u012b\u0096\u0002\u0497', 741 | '\u049a\u0005\u0129\u0095\u0002\u0498\u049a\t\u0003\u0002\u0002\u0499', 742 | '\u0496\u0003\u0002\u0002\u0002\u0499\u0497\u0003\u0002\u0002\u0002\u0499', 743 | '\u0498\u0003\u0002\u0002\u0002\u049a\u049d\u0003\u0002\u0002\u0002\u049b', 744 | '\u0499\u0003\u0002\u0002\u0002\u049b\u049c\u0003\u0002\u0002\u0002\u049c', 745 | '\u011c\u0003\u0002\u0002\u0002\u049d\u049b\u0003\u0002\u0002\u0002\u049e', 746 | '\u04a2\u0005\u0129\u0095\u0002\u049f\u04a3\u0005\u012b\u0096\u0002\u04a0', 747 | '\u04a3\u0005\u0129\u0095\u0002\u04a1\u04a3\t\u0003\u0002\u0002\u04a2', 748 | '\u049f\u0003\u0002\u0002\u0002\u04a2\u04a0\u0003\u0002\u0002\u0002\u04a2', 749 | '\u04a1\u0003\u0002\u0002\u0002\u04a3\u04a4\u0003\u0002\u0002\u0002\u04a4', 750 | '\u04a2\u0003\u0002\u0002\u0002\u04a4\u04a5\u0003\u0002\u0002\u0002\u04a5', 751 | '\u011e\u0003\u0002\u0002\u0002\u04a6\u04ac\u0007$\u0002\u0002\u04a7', 752 | '\u04ab\n\u0004\u0002\u0002\u04a8\u04a9\u0007$\u0002\u0002\u04a9\u04ab', 753 | '\u0007$\u0002\u0002\u04aa\u04a7\u0003\u0002\u0002\u0002\u04aa\u04a8', 754 | '\u0003\u0002\u0002\u0002\u04ab\u04ae\u0003\u0002\u0002\u0002\u04ac\u04aa', 755 | '\u0003\u0002\u0002\u0002\u04ac\u04ad\u0003\u0002\u0002\u0002\u04ad\u04af', 756 | '\u0003\u0002\u0002\u0002\u04ae\u04ac\u0003\u0002\u0002\u0002\u04af\u04b0', 757 | '\u0007$\u0002\u0002\u04b0\u0120\u0003\u0002\u0002\u0002\u04b1\u04b7', 758 | '\u0007b\u0002\u0002\u04b2\u04b6\n\u0005\u0002\u0002\u04b3\u04b4\u0007', 759 | 'b\u0002\u0002\u04b4\u04b6\u0007b\u0002\u0002\u04b5\u04b2\u0003\u0002', 760 | '\u0002\u0002\u04b5\u04b3\u0003\u0002\u0002\u0002\u04b6\u04b9\u0003\u0002', 761 | '\u0002\u0002\u04b7\u04b5\u0003\u0002\u0002\u0002\u04b7\u04b8\u0003\u0002', 762 | '\u0002\u0002\u04b8\u04ba\u0003\u0002\u0002\u0002\u04b9\u04b7\u0003\u0002', 763 | '\u0002\u0002\u04ba\u04bb\u0007b\u0002\u0002\u04bb\u0122\u0003\u0002', 764 | '\u0002\u0002\u04bc\u04bd\u0007V\u0002\u0002\u04bd\u04be\u0007K\u0002', 765 | '\u0002\u04be\u04bf\u0007O\u0002\u0002\u04bf\u04c0\u0007G\u0002\u0002', 766 | '\u04c0\u04c1\u0003\u0002\u0002\u0002\u04c1\u04c2\u0005\u0131\u0099\u0002', 767 | '\u04c2\u04c3\u0007Y\u0002\u0002\u04c3\u04c4\u0007K\u0002\u0002\u04c4', 768 | '\u04c5\u0007V\u0002\u0002\u04c5\u04c6\u0007J\u0002\u0002\u04c6\u04c7', 769 | '\u0003\u0002\u0002\u0002\u04c7\u04c8\u0005\u0131\u0099\u0002\u04c8\u04c9', 770 | '\u0007V\u0002\u0002\u04c9\u04ca\u0007K\u0002\u0002\u04ca\u04cb\u0007', 771 | 'O\u0002\u0002\u04cb\u04cc\u0007G\u0002\u0002\u04cc\u04cd\u0003\u0002', 772 | '\u0002\u0002\u04cd\u04ce\u0005\u0131\u0099\u0002\u04ce\u04cf\u0007\\', 773 | '\u0002\u0002\u04cf\u04d0\u0007Q\u0002\u0002\u04d0\u04d1\u0007P\u0002', 774 | '\u0002\u04d1\u04d2\u0007G\u0002\u0002\u04d2\u0124\u0003\u0002\u0002', 775 | '\u0002\u04d3\u04d4\u0007V\u0002\u0002\u04d4\u04d5\u0007K\u0002\u0002', 776 | '\u04d5\u04d6\u0007O\u0002\u0002\u04d6\u04d7\u0007G\u0002\u0002\u04d7', 777 | '\u04d8\u0007U\u0002\u0002\u04d8\u04d9\u0007V\u0002\u0002\u04d9\u04da', 778 | '\u0007C\u0002\u0002\u04da\u04db\u0007O\u0002\u0002\u04db\u04dc\u0007', 779 | 'R\u0002\u0002\u04dc\u04dd\u0003\u0002\u0002\u0002\u04dd\u04de\u0005', 780 | '\u0131\u0099\u0002\u04de\u04df\u0007Y\u0002\u0002\u04df\u04e0\u0007', 781 | 'K\u0002\u0002\u04e0\u04e1\u0007V\u0002\u0002\u04e1\u04e2\u0007J\u0002', 782 | '\u0002\u04e2\u04e3\u0003\u0002\u0002\u0002\u04e3\u04e4\u0005\u0131\u0099', 783 | '\u0002\u04e4\u04e5\u0007V\u0002\u0002\u04e5\u04e6\u0007K\u0002\u0002', 784 | '\u04e6\u04e7\u0007O\u0002\u0002\u04e7\u04e8\u0007G\u0002\u0002\u04e8', 785 | '\u04e9\u0003\u0002\u0002\u0002\u04e9\u04ea\u0005\u0131\u0099\u0002\u04ea', 786 | '\u04eb\u0007\\\u0002\u0002\u04eb\u04ec\u0007Q\u0002\u0002\u04ec\u04ed', 787 | '\u0007P\u0002\u0002\u04ed\u04ee\u0007G\u0002\u0002\u04ee\u0126\u0003', 788 | '\u0002\u0002\u0002\u04ef\u04f1\u0007G\u0002\u0002\u04f0\u04f2\t\u0006', 789 | '\u0002\u0002\u04f1\u04f0\u0003\u0002\u0002\u0002\u04f1\u04f2\u0003\u0002', 790 | '\u0002\u0002\u04f2\u04f4\u0003\u0002\u0002\u0002\u04f3\u04f5\u0005\u0129', 791 | '\u0095\u0002\u04f4\u04f3\u0003\u0002\u0002\u0002\u04f5\u04f6\u0003\u0002', 792 | '\u0002\u0002\u04f6\u04f4\u0003\u0002\u0002\u0002\u04f6\u04f7\u0003\u0002', 793 | '\u0002\u0002\u04f7\u0128\u0003\u0002\u0002\u0002\u04f8\u04f9\t\u0007', 794 | '\u0002\u0002\u04f9\u012a\u0003\u0002\u0002\u0002\u04fa\u04fb\t\b\u0002', 795 | '\u0002\u04fb\u012c\u0003\u0002\u0002\u0002\u04fc\u04fd\u0007/\u0002', 796 | '\u0002\u04fd\u04fe\u0007/\u0002\u0002\u04fe\u0502\u0003\u0002\u0002', 797 | '\u0002\u04ff\u0501\n\t\u0002\u0002\u0500\u04ff\u0003\u0002\u0002\u0002', 798 | '\u0501\u0504\u0003\u0002\u0002\u0002\u0502\u0500\u0003\u0002\u0002\u0002', 799 | '\u0502\u0503\u0003\u0002\u0002\u0002\u0503\u0506\u0003\u0002\u0002\u0002', 800 | '\u0504\u0502\u0003\u0002\u0002\u0002\u0505\u0507\u0007\u000f\u0002\u0002', 801 | '\u0506\u0505\u0003\u0002\u0002\u0002\u0506\u0507\u0003\u0002\u0002\u0002', 802 | '\u0507\u0509\u0003\u0002\u0002\u0002\u0508\u050a\u0007\f\u0002\u0002', 803 | '\u0509\u0508\u0003\u0002\u0002\u0002\u0509\u050a\u0003\u0002\u0002\u0002', 804 | '\u050a\u050b\u0003\u0002\u0002\u0002\u050b\u050c\b\u0097\u0002\u0002', 805 | '\u050c\u012e\u0003\u0002\u0002\u0002\u050d\u050e\u00071\u0002\u0002', 806 | '\u050e\u050f\u0007,\u0002\u0002\u050f\u0513\u0003\u0002\u0002\u0002', 807 | '\u0510\u0512\u000b\u0002\u0002\u0002\u0511\u0510\u0003\u0002\u0002\u0002', 808 | '\u0512\u0515\u0003\u0002\u0002\u0002\u0513\u0514\u0003\u0002\u0002\u0002', 809 | '\u0513\u0511\u0003\u0002\u0002\u0002\u0514\u0516\u0003\u0002\u0002\u0002', 810 | '\u0515\u0513\u0003\u0002\u0002\u0002\u0516\u0517\u0007,\u0002\u0002', 811 | '\u0517\u0518\u00071\u0002\u0002\u0518\u0519\u0003\u0002\u0002\u0002', 812 | '\u0519\u051a\b\u0098\u0002\u0002\u051a\u0130\u0003\u0002\u0002\u0002', 813 | '\u051b\u051d\t\n\u0002\u0002\u051c\u051b\u0003\u0002\u0002\u0002\u051d', 814 | '\u051e\u0003\u0002\u0002\u0002\u051e\u051c\u0003\u0002\u0002\u0002\u051e', 815 | '\u051f\u0003\u0002\u0002\u0002\u051f\u0520\u0003\u0002\u0002\u0002\u0520', 816 | '\u0521\b\u0099\u0002\u0002\u0521\u0132\u0003\u0002\u0002\u0002\u0522', 817 | '\u0523\u000b\u0002\u0002\u0002\u0523\u0134\u0003\u0002\u0002\u0002\u001f', 818 | '\u0002\u043a\u045a\u045c\u0464\u0469\u046f\u0476\u047b\u0481\u0484\u048c', 819 | '\u0490\u0494\u0499\u049b\u04a2\u04a4\u04aa\u04ac\u04b5\u04b7\u04f1\u04f6', 820 | '\u0502\u0506\u0509\u0513\u051e\u0003\u0002\u0003\u0002'].join('') 821 | 822 | var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN) 823 | 824 | var decisionsToDFA = atn.decisionToState.map(function(ds, index) { 825 | 826 | return new antlr4.dfa.DFA(ds, index) 827 | 828 | }) 829 | 830 | function SqlBaseLexer(input) { 831 | 832 | antlr4.Lexer.call(this, input) 833 | this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache()) 834 | return this 835 | 836 | } 837 | 838 | SqlBaseLexer.prototype = Object.create(antlr4.Lexer.prototype) 839 | SqlBaseLexer.prototype.constructor = SqlBaseLexer 840 | 841 | Object.defineProperty(SqlBaseLexer.prototype, 'atn', { 842 | get: function() { 843 | 844 | return atn 845 | 846 | } 847 | }) 848 | 849 | SqlBaseLexer.EOF = antlr4.Token.EOF 850 | SqlBaseLexer.T__0 = 1 851 | SqlBaseLexer.T__1 = 2 852 | SqlBaseLexer.T__2 = 3 853 | SqlBaseLexer.T__3 = 4 854 | SqlBaseLexer.T__4 = 5 855 | SqlBaseLexer.T__5 = 6 856 | SqlBaseLexer.T__6 = 7 857 | SqlBaseLexer.EMIT = 8 858 | SqlBaseLexer.CHANGES = 9 859 | SqlBaseLexer.SELECT = 10 860 | SqlBaseLexer.FROM = 11 861 | SqlBaseLexer.AS = 12 862 | SqlBaseLexer.DISTINCT = 13 863 | SqlBaseLexer.WHERE = 14 864 | SqlBaseLexer.WITHIN = 15 865 | SqlBaseLexer.WINDOW = 16 866 | SqlBaseLexer.GROUP = 17 867 | SqlBaseLexer.BY = 18 868 | SqlBaseLexer.HAVING = 19 869 | SqlBaseLexer.LIMIT = 20 870 | SqlBaseLexer.AT = 21 871 | SqlBaseLexer.OR = 22 872 | SqlBaseLexer.AND = 23 873 | SqlBaseLexer.IN = 24 874 | SqlBaseLexer.NOT = 25 875 | SqlBaseLexer.EXISTS = 26 876 | SqlBaseLexer.BETWEEN = 27 877 | SqlBaseLexer.LIKE = 28 878 | SqlBaseLexer.IS = 29 879 | SqlBaseLexer.NULL = 30 880 | SqlBaseLexer.TRUE = 31 881 | SqlBaseLexer.FALSE = 32 882 | SqlBaseLexer.INTEGER = 33 883 | SqlBaseLexer.DATE = 34 884 | SqlBaseLexer.TIME = 35 885 | SqlBaseLexer.TIMESTAMP = 36 886 | SqlBaseLexer.INTERVAL = 37 887 | SqlBaseLexer.YEAR = 38 888 | SqlBaseLexer.MONTH = 39 889 | SqlBaseLexer.DAY = 40 890 | SqlBaseLexer.HOUR = 41 891 | SqlBaseLexer.MINUTE = 42 892 | SqlBaseLexer.SECOND = 43 893 | SqlBaseLexer.MILLISECOND = 44 894 | SqlBaseLexer.YEARS = 45 895 | SqlBaseLexer.MONTHS = 46 896 | SqlBaseLexer.DAYS = 47 897 | SqlBaseLexer.HOURS = 48 898 | SqlBaseLexer.MINUTES = 49 899 | SqlBaseLexer.SECONDS = 50 900 | SqlBaseLexer.MILLISECONDS = 51 901 | SqlBaseLexer.ZONE = 52 902 | SqlBaseLexer.TUMBLING = 53 903 | SqlBaseLexer.HOPPING = 54 904 | SqlBaseLexer.SIZE = 55 905 | SqlBaseLexer.ADVANCE = 56 906 | SqlBaseLexer.CASE = 57 907 | SqlBaseLexer.WHEN = 58 908 | SqlBaseLexer.THEN = 59 909 | SqlBaseLexer.ELSE = 60 910 | SqlBaseLexer.END = 61 911 | SqlBaseLexer.JOIN = 62 912 | SqlBaseLexer.FULL = 63 913 | SqlBaseLexer.OUTER = 64 914 | SqlBaseLexer.INNER = 65 915 | SqlBaseLexer.LEFT = 66 916 | SqlBaseLexer.RIGHT = 67 917 | SqlBaseLexer.ON = 68 918 | SqlBaseLexer.PARTITION = 69 919 | SqlBaseLexer.STRUCT = 70 920 | SqlBaseLexer.WITH = 71 921 | SqlBaseLexer.VALUES = 72 922 | SqlBaseLexer.CREATE = 73 923 | SqlBaseLexer.TABLE = 74 924 | SqlBaseLexer.TOPIC = 75 925 | SqlBaseLexer.STREAM = 76 926 | SqlBaseLexer.STREAMS = 77 927 | SqlBaseLexer.INSERT = 78 928 | SqlBaseLexer.DELETE = 79 929 | SqlBaseLexer.INTO = 80 930 | SqlBaseLexer.DESCRIBE = 81 931 | SqlBaseLexer.EXTENDED = 82 932 | SqlBaseLexer.PRINT = 83 933 | SqlBaseLexer.EXPLAIN = 84 934 | SqlBaseLexer.ANALYZE = 85 935 | SqlBaseLexer.TYPE = 86 936 | SqlBaseLexer.TYPES = 87 937 | SqlBaseLexer.CAST = 88 938 | SqlBaseLexer.SHOW = 89 939 | SqlBaseLexer.LIST = 90 940 | SqlBaseLexer.TABLES = 91 941 | SqlBaseLexer.TOPICS = 92 942 | SqlBaseLexer.QUERY = 93 943 | SqlBaseLexer.QUERIES = 94 944 | SqlBaseLexer.TERMINATE = 95 945 | SqlBaseLexer.LOAD = 96 946 | SqlBaseLexer.COLUMNS = 97 947 | SqlBaseLexer.COLUMN = 98 948 | SqlBaseLexer.PARTITIONS = 99 949 | SqlBaseLexer.FUNCTIONS = 100 950 | SqlBaseLexer.FUNCTION = 101 951 | SqlBaseLexer.DROP = 102 952 | SqlBaseLexer.TO = 103 953 | SqlBaseLexer.RENAME = 104 954 | SqlBaseLexer.ARRAY = 105 955 | SqlBaseLexer.MAP = 106 956 | SqlBaseLexer.SET = 107 957 | SqlBaseLexer.RESET = 108 958 | SqlBaseLexer.SESSION = 109 959 | SqlBaseLexer.SAMPLE = 110 960 | SqlBaseLexer.EXPORT = 111 961 | SqlBaseLexer.CATALOG = 112 962 | SqlBaseLexer.PROPERTIES = 113 963 | SqlBaseLexer.BEGINNING = 114 964 | SqlBaseLexer.UNSET = 115 965 | SqlBaseLexer.RUN = 116 966 | SqlBaseLexer.SCRIPT = 117 967 | SqlBaseLexer.DECIMAL = 118 968 | SqlBaseLexer.KEY = 119 969 | SqlBaseLexer.CONNECTOR = 120 970 | SqlBaseLexer.CONNECTORS = 121 971 | SqlBaseLexer.SINK = 122 972 | SqlBaseLexer.SOURCE = 123 973 | SqlBaseLexer.IF = 124 974 | SqlBaseLexer.EQ = 125 975 | SqlBaseLexer.NEQ = 126 976 | SqlBaseLexer.LT = 127 977 | SqlBaseLexer.LTE = 128 978 | SqlBaseLexer.GT = 129 979 | SqlBaseLexer.GTE = 130 980 | SqlBaseLexer.PLUS = 131 981 | SqlBaseLexer.MINUS = 132 982 | SqlBaseLexer.ASTERISK = 133 983 | SqlBaseLexer.SLASH = 134 984 | SqlBaseLexer.PERCENT = 135 985 | SqlBaseLexer.CONCAT = 136 986 | SqlBaseLexer.STRUCT_FIELD_REF = 137 987 | SqlBaseLexer.STRING = 138 988 | SqlBaseLexer.INTEGER_VALUE = 139 989 | SqlBaseLexer.DECIMAL_VALUE = 140 990 | SqlBaseLexer.IDENTIFIER = 141 991 | SqlBaseLexer.DIGIT_IDENTIFIER = 142 992 | SqlBaseLexer.QUOTED_IDENTIFIER = 143 993 | SqlBaseLexer.BACKQUOTED_IDENTIFIER = 144 994 | SqlBaseLexer.TIME_WITH_TIME_ZONE = 145 995 | SqlBaseLexer.TIMESTAMP_WITH_TIME_ZONE = 146 996 | SqlBaseLexer.SIMPLE_COMMENT = 147 997 | SqlBaseLexer.BRACKETED_COMMENT = 148 998 | SqlBaseLexer.WS = 149 999 | SqlBaseLexer.UNRECOGNIZED = 150 1000 | 1001 | SqlBaseLexer.prototype.channelNames = [ 'DEFAULT_TOKEN_CHANNEL', 'HIDDEN' ] 1002 | 1003 | SqlBaseLexer.prototype.modeNames = [ 'DEFAULT_MODE' ] 1004 | 1005 | SqlBaseLexer.prototype.literalNames = [ null, "';'", "','", "'('", "')'", 1006 | "'.'", "'['", "']'", "'EMIT'", "'CHANGES'", 1007 | "'SELECT'", "'FROM'", "'AS'", "'DISTINCT'", 1008 | "'WHERE'", "'WITHIN'", "'WINDOW'", 1009 | "'GROUP'", "'BY'", "'HAVING'", "'LIMIT'", 1010 | "'AT'", "'OR'", "'AND'", "'IN'", 1011 | "'NOT'", "'EXISTS'", "'BETWEEN'", 1012 | "'LIKE'", "'IS'", "'NULL'", "'TRUE'", 1013 | "'FALSE'", "'INTEGER'", "'DATE'", 1014 | "'TIME'", "'TIMESTAMP'", "'INTERVAL'", 1015 | "'YEAR'", "'MONTH'", "'DAY'", "'HOUR'", 1016 | "'MINUTE'", "'SECOND'", "'MILLISECOND'", 1017 | "'YEARS'", "'MONTHS'", "'DAYS'", 1018 | "'HOURS'", "'MINUTES'", "'SECONDS'", 1019 | "'MILLISECONDS'", "'ZONE'", "'TUMBLING'", 1020 | "'HOPPING'", "'SIZE'", "'ADVANCE'", 1021 | "'CASE'", "'WHEN'", "'THEN'", "'ELSE'", 1022 | "'END'", "'JOIN'", "'FULL'", "'OUTER'", 1023 | "'INNER'", "'LEFT'", "'RIGHT'", 1024 | "'ON'", "'PARTITION'", "'STRUCT'", 1025 | "'WITH'", "'VALUES'", "'CREATE'", 1026 | "'TABLE'", "'TOPIC'", "'STREAM'", 1027 | "'STREAMS'", "'INSERT'", "'DELETE'", 1028 | "'INTO'", "'DESCRIBE'", "'EXTENDED'", 1029 | "'PRINT'", "'EXPLAIN'", "'ANALYZE'", 1030 | "'TYPE'", "'TYPES'", "'CAST'", "'SHOW'", 1031 | "'LIST'", "'TABLES'", "'TOPICS'", 1032 | "'QUERY'", "'QUERIES'", "'TERMINATE'", 1033 | "'LOAD'", "'COLUMNS'", "'COLUMN'", 1034 | "'PARTITIONS'", "'FUNCTIONS'", "'FUNCTION'", 1035 | "'DROP'", "'TO'", "'RENAME'", "'ARRAY'", 1036 | "'MAP'", "'SET'", "'RESET'", "'SESSION'", 1037 | "'SAMPLE'", "'EXPORT'", "'CATALOG'", 1038 | "'PROPERTIES'", "'BEGINNING'", "'UNSET'", 1039 | "'RUN'", "'SCRIPT'", "'DECIMAL'", 1040 | "'KEY'", "'CONNECTOR'", "'CONNECTORS'", 1041 | "'SINK'", "'SOURCE'", "'IF'", "'='", 1042 | null, "'<'", "'<='", "'>'", "'>='", 1043 | "'+'", "'-'", "'*'", "'/'", "'%'", 1044 | "'||'", "'->'" ] 1045 | 1046 | SqlBaseLexer.prototype.symbolicNames = [ null, null, null, null, null, null, 1047 | null, null, 'EMIT', 'CHANGES', 1048 | 'SELECT', 'FROM', 'AS', 'DISTINCT', 1049 | 'WHERE', 'WITHIN', 'WINDOW', 'GROUP', 1050 | 'BY', 'HAVING', 'LIMIT', 'AT', 1051 | 'OR', 'AND', 'IN', 'NOT', 'EXISTS', 1052 | 'BETWEEN', 'LIKE', 'IS', 'NULL', 1053 | 'TRUE', 'FALSE', 'INTEGER', 'DATE', 1054 | 'TIME', 'TIMESTAMP', 'INTERVAL', 1055 | 'YEAR', 'MONTH', 'DAY', 'HOUR', 1056 | 'MINUTE', 'SECOND', 'MILLISECOND', 1057 | 'YEARS', 'MONTHS', 'DAYS', 'HOURS', 1058 | 'MINUTES', 'SECONDS', 'MILLISECONDS', 1059 | 'ZONE', 'TUMBLING', 'HOPPING', 1060 | 'SIZE', 'ADVANCE', 'CASE', 'WHEN', 1061 | 'THEN', 'ELSE', 'END', 'JOIN', 1062 | 'FULL', 'OUTER', 'INNER', 'LEFT', 1063 | 'RIGHT', 'ON', 'PARTITION', 'STRUCT', 1064 | 'WITH', 'VALUES', 'CREATE', 'TABLE', 1065 | 'TOPIC', 'STREAM', 'STREAMS', 'INSERT', 1066 | 'DELETE', 'INTO', 'DESCRIBE', 'EXTENDED', 1067 | 'PRINT', 'EXPLAIN', 'ANALYZE', 1068 | 'TYPE', 'TYPES', 'CAST', 'SHOW', 1069 | 'LIST', 'TABLES', 'TOPICS', 'QUERY', 1070 | 'QUERIES', 'TERMINATE', 'LOAD', 1071 | 'COLUMNS', 'COLUMN', 'PARTITIONS', 1072 | 'FUNCTIONS', 'FUNCTION', 'DROP', 1073 | 'TO', 'RENAME', 'ARRAY', 'MAP', 1074 | 'SET', 'RESET', 'SESSION', 'SAMPLE', 1075 | 'EXPORT', 'CATALOG', 'PROPERTIES', 1076 | 'BEGINNING', 'UNSET', 'RUN', 'SCRIPT', 1077 | 'DECIMAL', 'KEY', 'CONNECTOR', 1078 | 'CONNECTORS', 'SINK', 'SOURCE', 1079 | 'IF', 'EQ', 'NEQ', 'LT', 'LTE', 1080 | 'GT', 'GTE', 'PLUS', 'MINUS', 'ASTERISK', 1081 | 'SLASH', 'PERCENT', 'CONCAT', 'STRUCT_FIELD_REF', 1082 | 'STRING', 'INTEGER_VALUE', 'DECIMAL_VALUE', 1083 | 'IDENTIFIER', 'DIGIT_IDENTIFIER', 1084 | 'QUOTED_IDENTIFIER', 'BACKQUOTED_IDENTIFIER', 1085 | 'TIME_WITH_TIME_ZONE', 'TIMESTAMP_WITH_TIME_ZONE', 1086 | 'SIMPLE_COMMENT', 'BRACKETED_COMMENT', 1087 | 'WS', 'UNRECOGNIZED' ] 1088 | 1089 | SqlBaseLexer.prototype.ruleNames = [ 'T__0', 'T__1', 'T__2', 'T__3', 'T__4', 1090 | 'T__5', 'T__6', 'EMIT', 'CHANGES', 1091 | 'SELECT', 'FROM', 'AS', 'DISTINCT', 1092 | 'WHERE', 'WITHIN', 'WINDOW', 'GROUP', 1093 | 'BY', 'HAVING', 'LIMIT', 'AT', 'OR', 1094 | 'AND', 'IN', 'NOT', 'EXISTS', 'BETWEEN', 1095 | 'LIKE', 'IS', 'NULL', 'TRUE', 'FALSE', 1096 | 'INTEGER', 'DATE', 'TIME', 'TIMESTAMP', 1097 | 'INTERVAL', 'YEAR', 'MONTH', 'DAY', 1098 | 'HOUR', 'MINUTE', 'SECOND', 'MILLISECOND', 1099 | 'YEARS', 'MONTHS', 'DAYS', 'HOURS', 1100 | 'MINUTES', 'SECONDS', 'MILLISECONDS', 1101 | 'ZONE', 'TUMBLING', 'HOPPING', 'SIZE', 1102 | 'ADVANCE', 'CASE', 'WHEN', 'THEN', 1103 | 'ELSE', 'END', 'JOIN', 'FULL', 'OUTER', 1104 | 'INNER', 'LEFT', 'RIGHT', 'ON', 'PARTITION', 1105 | 'STRUCT', 'WITH', 'VALUES', 'CREATE', 1106 | 'TABLE', 'TOPIC', 'STREAM', 'STREAMS', 1107 | 'INSERT', 'DELETE', 'INTO', 'DESCRIBE', 1108 | 'EXTENDED', 'PRINT', 'EXPLAIN', 'ANALYZE', 1109 | 'TYPE', 'TYPES', 'CAST', 'SHOW', 'LIST', 1110 | 'TABLES', 'TOPICS', 'QUERY', 'QUERIES', 1111 | 'TERMINATE', 'LOAD', 'COLUMNS', 'COLUMN', 1112 | 'PARTITIONS', 'FUNCTIONS', 'FUNCTION', 1113 | 'DROP', 'TO', 'RENAME', 'ARRAY', 'MAP', 1114 | 'SET', 'RESET', 'SESSION', 'SAMPLE', 1115 | 'EXPORT', 'CATALOG', 'PROPERTIES', 1116 | 'BEGINNING', 'UNSET', 'RUN', 'SCRIPT', 1117 | 'DECIMAL', 'KEY', 'CONNECTOR', 'CONNECTORS', 1118 | 'SINK', 'SOURCE', 'IF', 'EQ', 'NEQ', 1119 | 'LT', 'LTE', 'GT', 'GTE', 'PLUS', 'MINUS', 1120 | 'ASTERISK', 'SLASH', 'PERCENT', 'CONCAT', 1121 | 'STRUCT_FIELD_REF', 'STRING', 'INTEGER_VALUE', 1122 | 'DECIMAL_VALUE', 'IDENTIFIER', 'DIGIT_IDENTIFIER', 1123 | 'QUOTED_IDENTIFIER', 'BACKQUOTED_IDENTIFIER', 1124 | 'TIME_WITH_TIME_ZONE', 'TIMESTAMP_WITH_TIME_ZONE', 1125 | 'EXPONENT', 'DIGIT', 'LETTER', 'SIMPLE_COMMENT', 1126 | 'BRACKETED_COMMENT', 'WS', 'UNRECOGNIZED' ] 1127 | 1128 | SqlBaseLexer.prototype.grammarFileName = 'SqlBase.g4' 1129 | 1130 | exports.SqlBaseLexer = SqlBaseLexer 1131 | 1132 | -------------------------------------------------------------------------------- /src/parser/SqlBaseListener.js: -------------------------------------------------------------------------------- 1 | // Generated from SqlBase.g4 by ANTLR 4.7.2 2 | // jshint ignore: start 3 | var antlr4 = require('antlr4/index') 4 | 5 | // This class defines a complete listener for a parse tree produced by SqlBaseParser. 6 | function SqlBaseListener() { 7 | 8 | antlr4.tree.ParseTreeListener.call(this) 9 | return this 10 | 11 | } 12 | 13 | SqlBaseListener.prototype = Object.create(antlr4.tree.ParseTreeListener.prototype) 14 | SqlBaseListener.prototype.constructor = SqlBaseListener 15 | 16 | // Enter a parse tree produced by SqlBaseParser#statements. 17 | SqlBaseListener.prototype.enterStatements = function(ctx) { 18 | } 19 | 20 | // Exit a parse tree produced by SqlBaseParser#statements. 21 | SqlBaseListener.prototype.exitStatements = function(ctx) { 22 | } 23 | 24 | // Enter a parse tree produced by SqlBaseParser#singleStatement. 25 | SqlBaseListener.prototype.enterSingleStatement = function(ctx) { 26 | } 27 | 28 | // Exit a parse tree produced by SqlBaseParser#singleStatement. 29 | SqlBaseListener.prototype.exitSingleStatement = function(ctx) { 30 | } 31 | 32 | // Enter a parse tree produced by SqlBaseParser#singleExpression. 33 | SqlBaseListener.prototype.enterSingleExpression = function(ctx) { 34 | } 35 | 36 | // Exit a parse tree produced by SqlBaseParser#singleExpression. 37 | SqlBaseListener.prototype.exitSingleExpression = function(ctx) { 38 | } 39 | 40 | // Enter a parse tree produced by SqlBaseParser#queryStatement. 41 | SqlBaseListener.prototype.enterQueryStatement = function(ctx) { 42 | } 43 | 44 | // Exit a parse tree produced by SqlBaseParser#queryStatement. 45 | SqlBaseListener.prototype.exitQueryStatement = function(ctx) { 46 | } 47 | 48 | // Enter a parse tree produced by SqlBaseParser#listProperties. 49 | SqlBaseListener.prototype.enterListProperties = function(ctx) { 50 | } 51 | 52 | // Exit a parse tree produced by SqlBaseParser#listProperties. 53 | SqlBaseListener.prototype.exitListProperties = function(ctx) { 54 | } 55 | 56 | // Enter a parse tree produced by SqlBaseParser#listTopics. 57 | SqlBaseListener.prototype.enterListTopics = function(ctx) { 58 | } 59 | 60 | // Exit a parse tree produced by SqlBaseParser#listTopics. 61 | SqlBaseListener.prototype.exitListTopics = function(ctx) { 62 | } 63 | 64 | // Enter a parse tree produced by SqlBaseParser#listStreams. 65 | SqlBaseListener.prototype.enterListStreams = function(ctx) { 66 | } 67 | 68 | // Exit a parse tree produced by SqlBaseParser#listStreams. 69 | SqlBaseListener.prototype.exitListStreams = function(ctx) { 70 | } 71 | 72 | // Enter a parse tree produced by SqlBaseParser#listTables. 73 | SqlBaseListener.prototype.enterListTables = function(ctx) { 74 | } 75 | 76 | // Exit a parse tree produced by SqlBaseParser#listTables. 77 | SqlBaseListener.prototype.exitListTables = function(ctx) { 78 | } 79 | 80 | // Enter a parse tree produced by SqlBaseParser#listFunctions. 81 | SqlBaseListener.prototype.enterListFunctions = function(ctx) { 82 | } 83 | 84 | // Exit a parse tree produced by SqlBaseParser#listFunctions. 85 | SqlBaseListener.prototype.exitListFunctions = function(ctx) { 86 | } 87 | 88 | // Enter a parse tree produced by SqlBaseParser#listConnectors. 89 | SqlBaseListener.prototype.enterListConnectors = function(ctx) { 90 | } 91 | 92 | // Exit a parse tree produced by SqlBaseParser#listConnectors. 93 | SqlBaseListener.prototype.exitListConnectors = function(ctx) { 94 | } 95 | 96 | // Enter a parse tree produced by SqlBaseParser#listTypes. 97 | SqlBaseListener.prototype.enterListTypes = function(ctx) { 98 | } 99 | 100 | // Exit a parse tree produced by SqlBaseParser#listTypes. 101 | SqlBaseListener.prototype.exitListTypes = function(ctx) { 102 | } 103 | 104 | // Enter a parse tree produced by SqlBaseParser#showColumns. 105 | SqlBaseListener.prototype.enterShowColumns = function(ctx) { 106 | } 107 | 108 | // Exit a parse tree produced by SqlBaseParser#showColumns. 109 | SqlBaseListener.prototype.exitShowColumns = function(ctx) { 110 | } 111 | 112 | // Enter a parse tree produced by SqlBaseParser#describeFunction. 113 | SqlBaseListener.prototype.enterDescribeFunction = function(ctx) { 114 | } 115 | 116 | // Exit a parse tree produced by SqlBaseParser#describeFunction. 117 | SqlBaseListener.prototype.exitDescribeFunction = function(ctx) { 118 | } 119 | 120 | // Enter a parse tree produced by SqlBaseParser#describeConnector. 121 | SqlBaseListener.prototype.enterDescribeConnector = function(ctx) { 122 | } 123 | 124 | // Exit a parse tree produced by SqlBaseParser#describeConnector. 125 | SqlBaseListener.prototype.exitDescribeConnector = function(ctx) { 126 | } 127 | 128 | // Enter a parse tree produced by SqlBaseParser#printTopic. 129 | SqlBaseListener.prototype.enterPrintTopic = function(ctx) { 130 | } 131 | 132 | // Exit a parse tree produced by SqlBaseParser#printTopic. 133 | SqlBaseListener.prototype.exitPrintTopic = function(ctx) { 134 | } 135 | 136 | // Enter a parse tree produced by SqlBaseParser#listQueries. 137 | SqlBaseListener.prototype.enterListQueries = function(ctx) { 138 | } 139 | 140 | // Exit a parse tree produced by SqlBaseParser#listQueries. 141 | SqlBaseListener.prototype.exitListQueries = function(ctx) { 142 | } 143 | 144 | // Enter a parse tree produced by SqlBaseParser#terminateQuery. 145 | SqlBaseListener.prototype.enterTerminateQuery = function(ctx) { 146 | } 147 | 148 | // Exit a parse tree produced by SqlBaseParser#terminateQuery. 149 | SqlBaseListener.prototype.exitTerminateQuery = function(ctx) { 150 | } 151 | 152 | // Enter a parse tree produced by SqlBaseParser#setProperty. 153 | SqlBaseListener.prototype.enterSetProperty = function(ctx) { 154 | } 155 | 156 | // Exit a parse tree produced by SqlBaseParser#setProperty. 157 | SqlBaseListener.prototype.exitSetProperty = function(ctx) { 158 | } 159 | 160 | // Enter a parse tree produced by SqlBaseParser#unsetProperty. 161 | SqlBaseListener.prototype.enterUnsetProperty = function(ctx) { 162 | } 163 | 164 | // Exit a parse tree produced by SqlBaseParser#unsetProperty. 165 | SqlBaseListener.prototype.exitUnsetProperty = function(ctx) { 166 | } 167 | 168 | // Enter a parse tree produced by SqlBaseParser#createStream. 169 | SqlBaseListener.prototype.enterCreateStream = function(ctx) { 170 | } 171 | 172 | // Exit a parse tree produced by SqlBaseParser#createStream. 173 | SqlBaseListener.prototype.exitCreateStream = function(ctx) { 174 | } 175 | 176 | // Enter a parse tree produced by SqlBaseParser#createStreamAs. 177 | SqlBaseListener.prototype.enterCreateStreamAs = function(ctx) { 178 | } 179 | 180 | // Exit a parse tree produced by SqlBaseParser#createStreamAs. 181 | SqlBaseListener.prototype.exitCreateStreamAs = function(ctx) { 182 | } 183 | 184 | // Enter a parse tree produced by SqlBaseParser#createTable. 185 | SqlBaseListener.prototype.enterCreateTable = function(ctx) { 186 | } 187 | 188 | // Exit a parse tree produced by SqlBaseParser#createTable. 189 | SqlBaseListener.prototype.exitCreateTable = function(ctx) { 190 | } 191 | 192 | // Enter a parse tree produced by SqlBaseParser#createTableAs. 193 | SqlBaseListener.prototype.enterCreateTableAs = function(ctx) { 194 | } 195 | 196 | // Exit a parse tree produced by SqlBaseParser#createTableAs. 197 | SqlBaseListener.prototype.exitCreateTableAs = function(ctx) { 198 | } 199 | 200 | // Enter a parse tree produced by SqlBaseParser#createConnector. 201 | SqlBaseListener.prototype.enterCreateConnector = function(ctx) { 202 | } 203 | 204 | // Exit a parse tree produced by SqlBaseParser#createConnector. 205 | SqlBaseListener.prototype.exitCreateConnector = function(ctx) { 206 | } 207 | 208 | // Enter a parse tree produced by SqlBaseParser#insertInto. 209 | SqlBaseListener.prototype.enterInsertInto = function(ctx) { 210 | } 211 | 212 | // Exit a parse tree produced by SqlBaseParser#insertInto. 213 | SqlBaseListener.prototype.exitInsertInto = function(ctx) { 214 | } 215 | 216 | // Enter a parse tree produced by SqlBaseParser#insertValues. 217 | SqlBaseListener.prototype.enterInsertValues = function(ctx) { 218 | } 219 | 220 | // Exit a parse tree produced by SqlBaseParser#insertValues. 221 | SqlBaseListener.prototype.exitInsertValues = function(ctx) { 222 | } 223 | 224 | // Enter a parse tree produced by SqlBaseParser#dropStream. 225 | SqlBaseListener.prototype.enterDropStream = function(ctx) { 226 | } 227 | 228 | // Exit a parse tree produced by SqlBaseParser#dropStream. 229 | SqlBaseListener.prototype.exitDropStream = function(ctx) { 230 | } 231 | 232 | // Enter a parse tree produced by SqlBaseParser#dropTable. 233 | SqlBaseListener.prototype.enterDropTable = function(ctx) { 234 | } 235 | 236 | // Exit a parse tree produced by SqlBaseParser#dropTable. 237 | SqlBaseListener.prototype.exitDropTable = function(ctx) { 238 | } 239 | 240 | // Enter a parse tree produced by SqlBaseParser#dropConnector. 241 | SqlBaseListener.prototype.enterDropConnector = function(ctx) { 242 | } 243 | 244 | // Exit a parse tree produced by SqlBaseParser#dropConnector. 245 | SqlBaseListener.prototype.exitDropConnector = function(ctx) { 246 | } 247 | 248 | // Enter a parse tree produced by SqlBaseParser#explain. 249 | SqlBaseListener.prototype.enterExplain = function(ctx) { 250 | } 251 | 252 | // Exit a parse tree produced by SqlBaseParser#explain. 253 | SqlBaseListener.prototype.exitExplain = function(ctx) { 254 | } 255 | 256 | // Enter a parse tree produced by SqlBaseParser#runScript. 257 | SqlBaseListener.prototype.enterRunScript = function(ctx) { 258 | } 259 | 260 | // Exit a parse tree produced by SqlBaseParser#runScript. 261 | SqlBaseListener.prototype.exitRunScript = function(ctx) { 262 | } 263 | 264 | // Enter a parse tree produced by SqlBaseParser#registerType. 265 | SqlBaseListener.prototype.enterRegisterType = function(ctx) { 266 | } 267 | 268 | // Exit a parse tree produced by SqlBaseParser#registerType. 269 | SqlBaseListener.prototype.exitRegisterType = function(ctx) { 270 | } 271 | 272 | // Enter a parse tree produced by SqlBaseParser#dropType. 273 | SqlBaseListener.prototype.enterDropType = function(ctx) { 274 | } 275 | 276 | // Exit a parse tree produced by SqlBaseParser#dropType. 277 | SqlBaseListener.prototype.exitDropType = function(ctx) { 278 | } 279 | 280 | // Enter a parse tree produced by SqlBaseParser#query. 281 | SqlBaseListener.prototype.enterQuery = function(ctx) { 282 | } 283 | 284 | // Exit a parse tree produced by SqlBaseParser#query. 285 | SqlBaseListener.prototype.exitQuery = function(ctx) { 286 | } 287 | 288 | // Enter a parse tree produced by SqlBaseParser#resultMaterialization. 289 | SqlBaseListener.prototype.enterResultMaterialization = function(ctx) { 290 | } 291 | 292 | // Exit a parse tree produced by SqlBaseParser#resultMaterialization. 293 | SqlBaseListener.prototype.exitResultMaterialization = function(ctx) { 294 | } 295 | 296 | // Enter a parse tree produced by SqlBaseParser#tableElements. 297 | SqlBaseListener.prototype.enterTableElements = function(ctx) { 298 | } 299 | 300 | // Exit a parse tree produced by SqlBaseParser#tableElements. 301 | SqlBaseListener.prototype.exitTableElements = function(ctx) { 302 | } 303 | 304 | // Enter a parse tree produced by SqlBaseParser#tableElement. 305 | SqlBaseListener.prototype.enterTableElement = function(ctx) { 306 | } 307 | 308 | // Exit a parse tree produced by SqlBaseParser#tableElement. 309 | SqlBaseListener.prototype.exitTableElement = function(ctx) { 310 | } 311 | 312 | // Enter a parse tree produced by SqlBaseParser#tableProperties. 313 | SqlBaseListener.prototype.enterTableProperties = function(ctx) { 314 | } 315 | 316 | // Exit a parse tree produced by SqlBaseParser#tableProperties. 317 | SqlBaseListener.prototype.exitTableProperties = function(ctx) { 318 | } 319 | 320 | // Enter a parse tree produced by SqlBaseParser#tableProperty. 321 | SqlBaseListener.prototype.enterTableProperty = function(ctx) { 322 | } 323 | 324 | // Exit a parse tree produced by SqlBaseParser#tableProperty. 325 | SqlBaseListener.prototype.exitTableProperty = function(ctx) { 326 | } 327 | 328 | // Enter a parse tree produced by SqlBaseParser#printClause. 329 | SqlBaseListener.prototype.enterPrintClause = function(ctx) { 330 | } 331 | 332 | // Exit a parse tree produced by SqlBaseParser#printClause. 333 | SqlBaseListener.prototype.exitPrintClause = function(ctx) { 334 | } 335 | 336 | // Enter a parse tree produced by SqlBaseParser#intervalClause. 337 | SqlBaseListener.prototype.enterIntervalClause = function(ctx) { 338 | } 339 | 340 | // Exit a parse tree produced by SqlBaseParser#intervalClause. 341 | SqlBaseListener.prototype.exitIntervalClause = function(ctx) { 342 | } 343 | 344 | // Enter a parse tree produced by SqlBaseParser#limitClause. 345 | SqlBaseListener.prototype.enterLimitClause = function(ctx) { 346 | } 347 | 348 | // Exit a parse tree produced by SqlBaseParser#limitClause. 349 | SqlBaseListener.prototype.exitLimitClause = function(ctx) { 350 | } 351 | 352 | // Enter a parse tree produced by SqlBaseParser#windowExpression. 353 | SqlBaseListener.prototype.enterWindowExpression = function(ctx) { 354 | } 355 | 356 | // Exit a parse tree produced by SqlBaseParser#windowExpression. 357 | SqlBaseListener.prototype.exitWindowExpression = function(ctx) { 358 | } 359 | 360 | // Enter a parse tree produced by SqlBaseParser#tumblingWindowExpression. 361 | SqlBaseListener.prototype.enterTumblingWindowExpression = function(ctx) { 362 | } 363 | 364 | // Exit a parse tree produced by SqlBaseParser#tumblingWindowExpression. 365 | SqlBaseListener.prototype.exitTumblingWindowExpression = function(ctx) { 366 | } 367 | 368 | // Enter a parse tree produced by SqlBaseParser#hoppingWindowExpression. 369 | SqlBaseListener.prototype.enterHoppingWindowExpression = function(ctx) { 370 | } 371 | 372 | // Exit a parse tree produced by SqlBaseParser#hoppingWindowExpression. 373 | SqlBaseListener.prototype.exitHoppingWindowExpression = function(ctx) { 374 | } 375 | 376 | // Enter a parse tree produced by SqlBaseParser#sessionWindowExpression. 377 | SqlBaseListener.prototype.enterSessionWindowExpression = function(ctx) { 378 | } 379 | 380 | // Exit a parse tree produced by SqlBaseParser#sessionWindowExpression. 381 | SqlBaseListener.prototype.exitSessionWindowExpression = function(ctx) { 382 | } 383 | 384 | // Enter a parse tree produced by SqlBaseParser#windowUnit. 385 | SqlBaseListener.prototype.enterWindowUnit = function(ctx) { 386 | } 387 | 388 | // Exit a parse tree produced by SqlBaseParser#windowUnit. 389 | SqlBaseListener.prototype.exitWindowUnit = function(ctx) { 390 | } 391 | 392 | // Enter a parse tree produced by SqlBaseParser#groupBy. 393 | SqlBaseListener.prototype.enterGroupBy = function(ctx) { 394 | } 395 | 396 | // Exit a parse tree produced by SqlBaseParser#groupBy. 397 | SqlBaseListener.prototype.exitGroupBy = function(ctx) { 398 | } 399 | 400 | // Enter a parse tree produced by SqlBaseParser#singleGroupingSet. 401 | SqlBaseListener.prototype.enterSingleGroupingSet = function(ctx) { 402 | } 403 | 404 | // Exit a parse tree produced by SqlBaseParser#singleGroupingSet. 405 | SqlBaseListener.prototype.exitSingleGroupingSet = function(ctx) { 406 | } 407 | 408 | // Enter a parse tree produced by SqlBaseParser#groupingExpressions. 409 | SqlBaseListener.prototype.enterGroupingExpressions = function(ctx) { 410 | } 411 | 412 | // Exit a parse tree produced by SqlBaseParser#groupingExpressions. 413 | SqlBaseListener.prototype.exitGroupingExpressions = function(ctx) { 414 | } 415 | 416 | // Enter a parse tree produced by SqlBaseParser#values. 417 | SqlBaseListener.prototype.enterValues = function(ctx) { 418 | } 419 | 420 | // Exit a parse tree produced by SqlBaseParser#values. 421 | SqlBaseListener.prototype.exitValues = function(ctx) { 422 | } 423 | 424 | // Enter a parse tree produced by SqlBaseParser#selectSingle. 425 | SqlBaseListener.prototype.enterSelectSingle = function(ctx) { 426 | } 427 | 428 | // Exit a parse tree produced by SqlBaseParser#selectSingle. 429 | SqlBaseListener.prototype.exitSelectSingle = function(ctx) { 430 | } 431 | 432 | // Enter a parse tree produced by SqlBaseParser#selectAll. 433 | SqlBaseListener.prototype.enterSelectAll = function(ctx) { 434 | } 435 | 436 | // Exit a parse tree produced by SqlBaseParser#selectAll. 437 | SqlBaseListener.prototype.exitSelectAll = function(ctx) { 438 | } 439 | 440 | // Enter a parse tree produced by SqlBaseParser#joinRelation. 441 | SqlBaseListener.prototype.enterJoinRelation = function(ctx) { 442 | } 443 | 444 | // Exit a parse tree produced by SqlBaseParser#joinRelation. 445 | SqlBaseListener.prototype.exitJoinRelation = function(ctx) { 446 | } 447 | 448 | // Enter a parse tree produced by SqlBaseParser#relationDefault. 449 | SqlBaseListener.prototype.enterRelationDefault = function(ctx) { 450 | } 451 | 452 | // Exit a parse tree produced by SqlBaseParser#relationDefault. 453 | SqlBaseListener.prototype.exitRelationDefault = function(ctx) { 454 | } 455 | 456 | // Enter a parse tree produced by SqlBaseParser#innerJoin. 457 | SqlBaseListener.prototype.enterInnerJoin = function(ctx) { 458 | } 459 | 460 | // Exit a parse tree produced by SqlBaseParser#innerJoin. 461 | SqlBaseListener.prototype.exitInnerJoin = function(ctx) { 462 | } 463 | 464 | // Enter a parse tree produced by SqlBaseParser#outerJoin. 465 | SqlBaseListener.prototype.enterOuterJoin = function(ctx) { 466 | } 467 | 468 | // Exit a parse tree produced by SqlBaseParser#outerJoin. 469 | SqlBaseListener.prototype.exitOuterJoin = function(ctx) { 470 | } 471 | 472 | // Enter a parse tree produced by SqlBaseParser#leftJoin. 473 | SqlBaseListener.prototype.enterLeftJoin = function(ctx) { 474 | } 475 | 476 | // Exit a parse tree produced by SqlBaseParser#leftJoin. 477 | SqlBaseListener.prototype.exitLeftJoin = function(ctx) { 478 | } 479 | 480 | // Enter a parse tree produced by SqlBaseParser#joinWindow. 481 | SqlBaseListener.prototype.enterJoinWindow = function(ctx) { 482 | } 483 | 484 | // Exit a parse tree produced by SqlBaseParser#joinWindow. 485 | SqlBaseListener.prototype.exitJoinWindow = function(ctx) { 486 | } 487 | 488 | // Enter a parse tree produced by SqlBaseParser#joinWindowWithBeforeAndAfter. 489 | SqlBaseListener.prototype.enterJoinWindowWithBeforeAndAfter = function(ctx) { 490 | } 491 | 492 | // Exit a parse tree produced by SqlBaseParser#joinWindowWithBeforeAndAfter. 493 | SqlBaseListener.prototype.exitJoinWindowWithBeforeAndAfter = function(ctx) { 494 | } 495 | 496 | // Enter a parse tree produced by SqlBaseParser#singleJoinWindow. 497 | SqlBaseListener.prototype.enterSingleJoinWindow = function(ctx) { 498 | } 499 | 500 | // Exit a parse tree produced by SqlBaseParser#singleJoinWindow. 501 | SqlBaseListener.prototype.exitSingleJoinWindow = function(ctx) { 502 | } 503 | 504 | // Enter a parse tree produced by SqlBaseParser#joinWindowSize. 505 | SqlBaseListener.prototype.enterJoinWindowSize = function(ctx) { 506 | } 507 | 508 | // Exit a parse tree produced by SqlBaseParser#joinWindowSize. 509 | SqlBaseListener.prototype.exitJoinWindowSize = function(ctx) { 510 | } 511 | 512 | // Enter a parse tree produced by SqlBaseParser#joinCriteria. 513 | SqlBaseListener.prototype.enterJoinCriteria = function(ctx) { 514 | } 515 | 516 | // Exit a parse tree produced by SqlBaseParser#joinCriteria. 517 | SqlBaseListener.prototype.exitJoinCriteria = function(ctx) { 518 | } 519 | 520 | // Enter a parse tree produced by SqlBaseParser#aliasedRelation. 521 | SqlBaseListener.prototype.enterAliasedRelation = function(ctx) { 522 | } 523 | 524 | // Exit a parse tree produced by SqlBaseParser#aliasedRelation. 525 | SqlBaseListener.prototype.exitAliasedRelation = function(ctx) { 526 | } 527 | 528 | // Enter a parse tree produced by SqlBaseParser#columns. 529 | SqlBaseListener.prototype.enterColumns = function(ctx) { 530 | } 531 | 532 | // Exit a parse tree produced by SqlBaseParser#columns. 533 | SqlBaseListener.prototype.exitColumns = function(ctx) { 534 | } 535 | 536 | // Enter a parse tree produced by SqlBaseParser#tableName. 537 | SqlBaseListener.prototype.enterTableName = function(ctx) { 538 | } 539 | 540 | // Exit a parse tree produced by SqlBaseParser#tableName. 541 | SqlBaseListener.prototype.exitTableName = function(ctx) { 542 | } 543 | 544 | // Enter a parse tree produced by SqlBaseParser#expression. 545 | SqlBaseListener.prototype.enterExpression = function(ctx) { 546 | } 547 | 548 | // Exit a parse tree produced by SqlBaseParser#expression. 549 | SqlBaseListener.prototype.exitExpression = function(ctx) { 550 | } 551 | 552 | // Enter a parse tree produced by SqlBaseParser#logicalNot. 553 | SqlBaseListener.prototype.enterLogicalNot = function(ctx) { 554 | } 555 | 556 | // Exit a parse tree produced by SqlBaseParser#logicalNot. 557 | SqlBaseListener.prototype.exitLogicalNot = function(ctx) { 558 | } 559 | 560 | // Enter a parse tree produced by SqlBaseParser#booleanDefault. 561 | SqlBaseListener.prototype.enterBooleanDefault = function(ctx) { 562 | } 563 | 564 | // Exit a parse tree produced by SqlBaseParser#booleanDefault. 565 | SqlBaseListener.prototype.exitBooleanDefault = function(ctx) { 566 | } 567 | 568 | // Enter a parse tree produced by SqlBaseParser#logicalBinary. 569 | SqlBaseListener.prototype.enterLogicalBinary = function(ctx) { 570 | } 571 | 572 | // Exit a parse tree produced by SqlBaseParser#logicalBinary. 573 | SqlBaseListener.prototype.exitLogicalBinary = function(ctx) { 574 | } 575 | 576 | // Enter a parse tree produced by SqlBaseParser#predicated. 577 | SqlBaseListener.prototype.enterPredicated = function(ctx) { 578 | } 579 | 580 | // Exit a parse tree produced by SqlBaseParser#predicated. 581 | SqlBaseListener.prototype.exitPredicated = function(ctx) { 582 | } 583 | 584 | // Enter a parse tree produced by SqlBaseParser#comparison. 585 | SqlBaseListener.prototype.enterComparison = function(ctx) { 586 | } 587 | 588 | // Exit a parse tree produced by SqlBaseParser#comparison. 589 | SqlBaseListener.prototype.exitComparison = function(ctx) { 590 | } 591 | 592 | // Enter a parse tree produced by SqlBaseParser#between. 593 | SqlBaseListener.prototype.enterBetween = function(ctx) { 594 | } 595 | 596 | // Exit a parse tree produced by SqlBaseParser#between. 597 | SqlBaseListener.prototype.exitBetween = function(ctx) { 598 | } 599 | 600 | // Enter a parse tree produced by SqlBaseParser#inList. 601 | SqlBaseListener.prototype.enterInList = function(ctx) { 602 | } 603 | 604 | // Exit a parse tree produced by SqlBaseParser#inList. 605 | SqlBaseListener.prototype.exitInList = function(ctx) { 606 | } 607 | 608 | // Enter a parse tree produced by SqlBaseParser#like. 609 | SqlBaseListener.prototype.enterLike = function(ctx) { 610 | } 611 | 612 | // Exit a parse tree produced by SqlBaseParser#like. 613 | SqlBaseListener.prototype.exitLike = function(ctx) { 614 | } 615 | 616 | // Enter a parse tree produced by SqlBaseParser#nullPredicate. 617 | SqlBaseListener.prototype.enterNullPredicate = function(ctx) { 618 | } 619 | 620 | // Exit a parse tree produced by SqlBaseParser#nullPredicate. 621 | SqlBaseListener.prototype.exitNullPredicate = function(ctx) { 622 | } 623 | 624 | // Enter a parse tree produced by SqlBaseParser#distinctFrom. 625 | SqlBaseListener.prototype.enterDistinctFrom = function(ctx) { 626 | } 627 | 628 | // Exit a parse tree produced by SqlBaseParser#distinctFrom. 629 | SqlBaseListener.prototype.exitDistinctFrom = function(ctx) { 630 | } 631 | 632 | // Enter a parse tree produced by SqlBaseParser#valueExpressionDefault. 633 | SqlBaseListener.prototype.enterValueExpressionDefault = function(ctx) { 634 | } 635 | 636 | // Exit a parse tree produced by SqlBaseParser#valueExpressionDefault. 637 | SqlBaseListener.prototype.exitValueExpressionDefault = function(ctx) { 638 | } 639 | 640 | // Enter a parse tree produced by SqlBaseParser#concatenation. 641 | SqlBaseListener.prototype.enterConcatenation = function(ctx) { 642 | } 643 | 644 | // Exit a parse tree produced by SqlBaseParser#concatenation. 645 | SqlBaseListener.prototype.exitConcatenation = function(ctx) { 646 | } 647 | 648 | // Enter a parse tree produced by SqlBaseParser#arithmeticBinary. 649 | SqlBaseListener.prototype.enterArithmeticBinary = function(ctx) { 650 | } 651 | 652 | // Exit a parse tree produced by SqlBaseParser#arithmeticBinary. 653 | SqlBaseListener.prototype.exitArithmeticBinary = function(ctx) { 654 | } 655 | 656 | // Enter a parse tree produced by SqlBaseParser#arithmeticUnary. 657 | SqlBaseListener.prototype.enterArithmeticUnary = function(ctx) { 658 | } 659 | 660 | // Exit a parse tree produced by SqlBaseParser#arithmeticUnary. 661 | SqlBaseListener.prototype.exitArithmeticUnary = function(ctx) { 662 | } 663 | 664 | // Enter a parse tree produced by SqlBaseParser#atTimeZone. 665 | SqlBaseListener.prototype.enterAtTimeZone = function(ctx) { 666 | } 667 | 668 | // Exit a parse tree produced by SqlBaseParser#atTimeZone. 669 | SqlBaseListener.prototype.exitAtTimeZone = function(ctx) { 670 | } 671 | 672 | // Enter a parse tree produced by SqlBaseParser#dereference. 673 | SqlBaseListener.prototype.enterDereference = function(ctx) { 674 | } 675 | 676 | // Exit a parse tree produced by SqlBaseParser#dereference. 677 | SqlBaseListener.prototype.exitDereference = function(ctx) { 678 | } 679 | 680 | // Enter a parse tree produced by SqlBaseParser#simpleCase. 681 | SqlBaseListener.prototype.enterSimpleCase = function(ctx) { 682 | } 683 | 684 | // Exit a parse tree produced by SqlBaseParser#simpleCase. 685 | SqlBaseListener.prototype.exitSimpleCase = function(ctx) { 686 | } 687 | 688 | // Enter a parse tree produced by SqlBaseParser#cast. 689 | SqlBaseListener.prototype.enterCast = function(ctx) { 690 | } 691 | 692 | // Exit a parse tree produced by SqlBaseParser#cast. 693 | SqlBaseListener.prototype.exitCast = function(ctx) { 694 | } 695 | 696 | // Enter a parse tree produced by SqlBaseParser#columnReference. 697 | SqlBaseListener.prototype.enterColumnReference = function(ctx) { 698 | } 699 | 700 | // Exit a parse tree produced by SqlBaseParser#columnReference. 701 | SqlBaseListener.prototype.exitColumnReference = function(ctx) { 702 | } 703 | 704 | // Enter a parse tree produced by SqlBaseParser#parenthesizedExpression. 705 | SqlBaseListener.prototype.enterParenthesizedExpression = function(ctx) { 706 | } 707 | 708 | // Exit a parse tree produced by SqlBaseParser#parenthesizedExpression. 709 | SqlBaseListener.prototype.exitParenthesizedExpression = function(ctx) { 710 | } 711 | 712 | // Enter a parse tree produced by SqlBaseParser#subscript. 713 | SqlBaseListener.prototype.enterSubscript = function(ctx) { 714 | } 715 | 716 | // Exit a parse tree produced by SqlBaseParser#subscript. 717 | SqlBaseListener.prototype.exitSubscript = function(ctx) { 718 | } 719 | 720 | // Enter a parse tree produced by SqlBaseParser#typeConstructor. 721 | SqlBaseListener.prototype.enterTypeConstructor = function(ctx) { 722 | } 723 | 724 | // Exit a parse tree produced by SqlBaseParser#typeConstructor. 725 | SqlBaseListener.prototype.exitTypeConstructor = function(ctx) { 726 | } 727 | 728 | // Enter a parse tree produced by SqlBaseParser#arrayConstructor. 729 | SqlBaseListener.prototype.enterArrayConstructor = function(ctx) { 730 | } 731 | 732 | // Exit a parse tree produced by SqlBaseParser#arrayConstructor. 733 | SqlBaseListener.prototype.exitArrayConstructor = function(ctx) { 734 | } 735 | 736 | // Enter a parse tree produced by SqlBaseParser#functionCall. 737 | SqlBaseListener.prototype.enterFunctionCall = function(ctx) { 738 | } 739 | 740 | // Exit a parse tree produced by SqlBaseParser#functionCall. 741 | SqlBaseListener.prototype.exitFunctionCall = function(ctx) { 742 | } 743 | 744 | // Enter a parse tree produced by SqlBaseParser#searchedCase. 745 | SqlBaseListener.prototype.enterSearchedCase = function(ctx) { 746 | } 747 | 748 | // Exit a parse tree produced by SqlBaseParser#searchedCase. 749 | SqlBaseListener.prototype.exitSearchedCase = function(ctx) { 750 | } 751 | 752 | // Enter a parse tree produced by SqlBaseParser#literalExpression. 753 | SqlBaseListener.prototype.enterLiteralExpression = function(ctx) { 754 | } 755 | 756 | // Exit a parse tree produced by SqlBaseParser#literalExpression. 757 | SqlBaseListener.prototype.exitLiteralExpression = function(ctx) { 758 | } 759 | 760 | // Enter a parse tree produced by SqlBaseParser#timeZoneString. 761 | SqlBaseListener.prototype.enterTimeZoneString = function(ctx) { 762 | } 763 | 764 | // Exit a parse tree produced by SqlBaseParser#timeZoneString. 765 | SqlBaseListener.prototype.exitTimeZoneString = function(ctx) { 766 | } 767 | 768 | // Enter a parse tree produced by SqlBaseParser#comparisonOperator. 769 | SqlBaseListener.prototype.enterComparisonOperator = function(ctx) { 770 | } 771 | 772 | // Exit a parse tree produced by SqlBaseParser#comparisonOperator. 773 | SqlBaseListener.prototype.exitComparisonOperator = function(ctx) { 774 | } 775 | 776 | // Enter a parse tree produced by SqlBaseParser#booleanValue. 777 | SqlBaseListener.prototype.enterBooleanValue = function(ctx) { 778 | } 779 | 780 | // Exit a parse tree produced by SqlBaseParser#booleanValue. 781 | SqlBaseListener.prototype.exitBooleanValue = function(ctx) { 782 | } 783 | 784 | // Enter a parse tree produced by SqlBaseParser#type. 785 | SqlBaseListener.prototype.enterType = function(ctx) { 786 | } 787 | 788 | // Exit a parse tree produced by SqlBaseParser#type. 789 | SqlBaseListener.prototype.exitType = function(ctx) { 790 | } 791 | 792 | // Enter a parse tree produced by SqlBaseParser#typeParameter. 793 | SqlBaseListener.prototype.enterTypeParameter = function(ctx) { 794 | } 795 | 796 | // Exit a parse tree produced by SqlBaseParser#typeParameter. 797 | SqlBaseListener.prototype.exitTypeParameter = function(ctx) { 798 | } 799 | 800 | // Enter a parse tree produced by SqlBaseParser#baseType. 801 | SqlBaseListener.prototype.enterBaseType = function(ctx) { 802 | } 803 | 804 | // Exit a parse tree produced by SqlBaseParser#baseType. 805 | SqlBaseListener.prototype.exitBaseType = function(ctx) { 806 | } 807 | 808 | // Enter a parse tree produced by SqlBaseParser#whenClause. 809 | SqlBaseListener.prototype.enterWhenClause = function(ctx) { 810 | } 811 | 812 | // Exit a parse tree produced by SqlBaseParser#whenClause. 813 | SqlBaseListener.prototype.exitWhenClause = function(ctx) { 814 | } 815 | 816 | // Enter a parse tree produced by SqlBaseParser#unquotedIdentifier. 817 | SqlBaseListener.prototype.enterUnquotedIdentifier = function(ctx) { 818 | } 819 | 820 | // Exit a parse tree produced by SqlBaseParser#unquotedIdentifier. 821 | SqlBaseListener.prototype.exitUnquotedIdentifier = function(ctx) { 822 | } 823 | 824 | // Enter a parse tree produced by SqlBaseParser#quotedIdentifierAlternative. 825 | SqlBaseListener.prototype.enterQuotedIdentifierAlternative = function(ctx) { 826 | } 827 | 828 | // Exit a parse tree produced by SqlBaseParser#quotedIdentifierAlternative. 829 | SqlBaseListener.prototype.exitQuotedIdentifierAlternative = function(ctx) { 830 | } 831 | 832 | // Enter a parse tree produced by SqlBaseParser#backQuotedIdentifier. 833 | SqlBaseListener.prototype.enterBackQuotedIdentifier = function(ctx) { 834 | } 835 | 836 | // Exit a parse tree produced by SqlBaseParser#backQuotedIdentifier. 837 | SqlBaseListener.prototype.exitBackQuotedIdentifier = function(ctx) { 838 | } 839 | 840 | // Enter a parse tree produced by SqlBaseParser#digitIdentifier. 841 | SqlBaseListener.prototype.enterDigitIdentifier = function(ctx) { 842 | } 843 | 844 | // Exit a parse tree produced by SqlBaseParser#digitIdentifier. 845 | SqlBaseListener.prototype.exitDigitIdentifier = function(ctx) { 846 | } 847 | 848 | // Enter a parse tree produced by SqlBaseParser#sourceName. 849 | SqlBaseListener.prototype.enterSourceName = function(ctx) { 850 | } 851 | 852 | // Exit a parse tree produced by SqlBaseParser#sourceName. 853 | SqlBaseListener.prototype.exitSourceName = function(ctx) { 854 | } 855 | 856 | // Enter a parse tree produced by SqlBaseParser#decimalLiteral. 857 | SqlBaseListener.prototype.enterDecimalLiteral = function(ctx) { 858 | } 859 | 860 | // Exit a parse tree produced by SqlBaseParser#decimalLiteral. 861 | SqlBaseListener.prototype.exitDecimalLiteral = function(ctx) { 862 | } 863 | 864 | // Enter a parse tree produced by SqlBaseParser#integerLiteral. 865 | SqlBaseListener.prototype.enterIntegerLiteral = function(ctx) { 866 | } 867 | 868 | // Exit a parse tree produced by SqlBaseParser#integerLiteral. 869 | SqlBaseListener.prototype.exitIntegerLiteral = function(ctx) { 870 | } 871 | 872 | // Enter a parse tree produced by SqlBaseParser#nullLiteral. 873 | SqlBaseListener.prototype.enterNullLiteral = function(ctx) { 874 | } 875 | 876 | // Exit a parse tree produced by SqlBaseParser#nullLiteral. 877 | SqlBaseListener.prototype.exitNullLiteral = function(ctx) { 878 | } 879 | 880 | // Enter a parse tree produced by SqlBaseParser#numericLiteral. 881 | SqlBaseListener.prototype.enterNumericLiteral = function(ctx) { 882 | } 883 | 884 | // Exit a parse tree produced by SqlBaseParser#numericLiteral. 885 | SqlBaseListener.prototype.exitNumericLiteral = function(ctx) { 886 | } 887 | 888 | // Enter a parse tree produced by SqlBaseParser#booleanLiteral. 889 | SqlBaseListener.prototype.enterBooleanLiteral = function(ctx) { 890 | } 891 | 892 | // Exit a parse tree produced by SqlBaseParser#booleanLiteral. 893 | SqlBaseListener.prototype.exitBooleanLiteral = function(ctx) { 894 | } 895 | 896 | // Enter a parse tree produced by SqlBaseParser#stringLiteral. 897 | SqlBaseListener.prototype.enterStringLiteral = function(ctx) { 898 | } 899 | 900 | // Exit a parse tree produced by SqlBaseParser#stringLiteral. 901 | SqlBaseListener.prototype.exitStringLiteral = function(ctx) { 902 | } 903 | 904 | // Enter a parse tree produced by SqlBaseParser#nonReserved. 905 | SqlBaseListener.prototype.enterNonReserved = function(ctx) { 906 | } 907 | 908 | // Exit a parse tree produced by SqlBaseParser#nonReserved. 909 | SqlBaseListener.prototype.exitNonReserved = function(ctx) { 910 | } 911 | 912 | exports.SqlBaseListener = SqlBaseListener 913 | -------------------------------------------------------------------------------- /src/parser/SyntaxErrorHandler.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | Copyright 2019 Carnegie Technologies 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | ***********************************************************************/ 16 | 17 | const antlr4 = require('antlr4') 18 | 19 | // class for gathering errors and returning nice feedback 20 | var SyntaxErrorHandler = function (annotations) { 21 | 22 | antlr4.error.ErrorListener.call(this) 23 | this.annotations = annotations 24 | return this 25 | 26 | } 27 | 28 | SyntaxErrorHandler.prototype = Object.create(antlr4.error.ErrorListener.prototype) 29 | SyntaxErrorHandler.prototype.constructor = SyntaxErrorHandler 30 | 31 | SyntaxErrorHandler.prototype.syntaxError = function (recognizer, offendingSymbol, line, column, msg, e) { 32 | 33 | // just a way to grab the relevant error details 34 | this.annotations.push({ 35 | row: line - 1, 36 | column: column, 37 | text: msg, 38 | type: 'error' 39 | }) 40 | 41 | } 42 | 43 | exports.SyntaxErrorHandler = SyntaxErrorHandler 44 | -------------------------------------------------------------------------------- /src/parser/index.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | Copyright 2019 Carnegie Technologies 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | ***********************************************************************/ 16 | 17 | const antlr4 = require('antlr4') 18 | const SqlBaseLexer = require('./SqlBaseLexer') 19 | const SqlBaseParser = require('./SqlBaseParser') 20 | const NameExtractor = require('./nameExtractor') 21 | const SyntaxErrorHandler = require('./SyntaxErrorHandler') 22 | const replacer = require('./replacer') 23 | 24 | // run the parser with custom syntax error handling 25 | function parse(input) { 26 | 27 | const chars = new antlr4.InputStream(input) 28 | const lexer = new SqlBaseLexer.SqlBaseLexer(chars) 29 | const tokens = new antlr4.CommonTokenStream(lexer) 30 | const parser = new SqlBaseParser.SqlBaseParser(tokens) 31 | parser.annotations = [] 32 | const SyntaxHandler = new SyntaxErrorHandler.SyntaxErrorHandler(parser.annotations) 33 | parser.removeErrorListeners() 34 | parser.addErrorListener(SyntaxHandler) 35 | parser.buildParseTrees = true 36 | return parser 37 | 38 | } 39 | 40 | // return sink/source topics from statements 41 | function readRelations(statements) { 42 | 43 | var listener = new NameExtractor.NameExtractor() 44 | antlr4.tree.ParseTreeWalker.DEFAULT.walk(listener, statements) 45 | return { 46 | created: listener.created, 47 | from: listener.from, 48 | fromTopic: listener.fromTopic 49 | } 50 | 51 | } 52 | 53 | module.exports.parse = parse 54 | module.exports.readRelations = readRelations 55 | module.exports.replace = replacer 56 | -------------------------------------------------------------------------------- /src/parser/nameExtractor.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | Copyright 2019 Carnegie Technologies 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | ***********************************************************************/ 16 | 17 | var SqlBaseListener = require('./SqlBaseListener').SqlBaseListener 18 | 19 | // This class defines a complete listener for a parse tree produced by SqlBaseParser. 20 | function NameExtractor() { 21 | 22 | SqlBaseListener.call(this) 23 | this.created = [] 24 | this.from = [] 25 | this.text = '' 26 | this.fromTopic = false 27 | return this 28 | 29 | } 30 | 31 | NameExtractor.prototype = Object.create(SqlBaseListener.prototype) 32 | NameExtractor.prototype.constructor = NameExtractor 33 | 34 | // Enter a parse tree produced by SqlBaseParser#createStream. 35 | NameExtractor.prototype.enterCreateStream = function (ctx) { 36 | 37 | this.created.push(ctx.sourceName().getText().toLowerCase()) 38 | this.fromTopic = true 39 | 40 | } 41 | 42 | // Enter a parse tree produced by SqlBaseParser#createStreamAs. 43 | NameExtractor.prototype.enterCreateStreamAs = function (ctx) { 44 | 45 | this.created.push(ctx.sourceName().getText().toLowerCase()) 46 | 47 | } 48 | 49 | // Enter a parse tree produced by SqlBaseParser#createTable. 50 | NameExtractor.prototype.enterCreateTable = function (ctx) { 51 | 52 | this.created.push(ctx.sourceName().getText().toLowerCase()) 53 | this.fromTopic = true 54 | 55 | } 56 | 57 | // Enter a parse tree produced by SqlBaseParser#createTableAs. 58 | NameExtractor.prototype.enterCreateTableAs = function (ctx) { 59 | 60 | this.created.push(ctx.sourceName().getText().toLowerCase()) 61 | 62 | } 63 | 64 | // Enter a parse tree produced by SqlBaseParser#tableProperty. 65 | NameExtractor.prototype.enterTableProperty = function (ctx) { 66 | 67 | if (ctx.identifier().getText() === 'KAFKA_TOPIC') { 68 | 69 | this.from.push( 70 | ctx.literal().getText().toLowerCase().replace(/['"]/g, '') 71 | ) 72 | 73 | } 74 | 75 | } 76 | 77 | // Enter a parse tree produced by SqlBaseParser#tableName. 78 | NameExtractor.prototype.enterRelationPrimary = function (ctx) { 79 | 80 | this.from.push(ctx.sourceName().getText().toLowerCase()) 81 | 82 | } 83 | 84 | // Enter a parse tree produced by SqlBaseParser#tableName. 85 | NameExtractor.prototype.enterTableName = function (ctx) { 86 | 87 | this.from.push(ctx.getText().toLowerCase()) 88 | 89 | } 90 | 91 | exports.NameExtractor = NameExtractor 92 | -------------------------------------------------------------------------------- /src/parser/replacer.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | Copyright 2019 Carnegie Technologies 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | ***********************************************************************/ 16 | 17 | function leaf (node) { 18 | 19 | return node.children && node.children.length ? leaf(node.children[0]) : node 20 | 21 | } 22 | 23 | const replacers = { 24 | tz: (node, value) => { 25 | 26 | if (node.children.length > 6) { 27 | 28 | let tz = leaf(node.children[node.children.length - 2]) 29 | tz.symbol._text = value 30 | 31 | } 32 | return false 33 | 34 | } 35 | } 36 | 37 | function performReplacement(rules, rulename, text, node) { 38 | 39 | for (let r in rules) { 40 | 41 | let parts = r.split('/') 42 | if (parts[0].toLowerCase() !== rulename.toLowerCase()) continue 43 | if (parts.length === 1) return rules[r] 44 | if (parts[1].toLowerCase() === text.toLowerCase()) { 45 | 46 | if (parts.length === 2) return rules[r] 47 | if (replacers[parts[2]]) return replacers[parts[2]](node, rules[r]) 48 | 49 | } 50 | 51 | } 52 | return false 53 | 54 | } 55 | 56 | function applyParameters(ast, w, node) { 57 | 58 | let replaced 59 | switch (ast.ruleNames[node.ruleIndex]) { 60 | 61 | case 'tableProperty': 62 | replaced = performReplacement(w.replacements, 'WITH', node.children[0].getText(), node) 63 | if (replaced !== false) { 64 | 65 | let l = leaf(node.children[2]) 66 | l.symbol._text = replaced 67 | 68 | } 69 | break 70 | case 'timeZoneSpecifier': 71 | replaced = performReplacement(w.replacements, 'TIME ZONE', node.children[0].getText(), node) 72 | if (replaced !== false) { 73 | 74 | let l = leaf(node.children[2]) 75 | l.symbol._text = replaced 76 | 77 | } 78 | break 79 | case 'primaryExpression': 80 | // function calls are always 3 sub expresssions or more 81 | // start with an identifier followed by '(' 82 | // and are not named 'cast' ;) 83 | if (node.children.length < 3 || 84 | node.children[0].getText().toLowerCase() === 'cast' || 85 | node.children[1].getText() !== '(') break 86 | // probably a function call 87 | performReplacement(w.replacements, 'FUNCTION', node.children[0].getText(), node) 88 | break 89 | 90 | } 91 | 92 | } 93 | 94 | function replacer(tree, replacements) { 95 | 96 | const lineBreakWords = ['FROM', 'WINDOW', 'GROUP', 'HAVING', 'EMIT', 'WITH'] 97 | const indentTwoRules = ['tableElements', 'limitClause'] 98 | const indentThreeRules = ['tableElement', 'tableProperty', 'selectItem'] 99 | const pad = i => (new Array(i >= 0 ? i : 0)).fill(' ').join('') 100 | const ast = tree.parser 101 | const walk = { 102 | skipSpace: true, 103 | newLine: false, 104 | indent: 0, 105 | statements: 1, 106 | format: true, 107 | replacements: {}, 108 | visitChildren: (node) => { 109 | 110 | if (!node) return 111 | if (node.children) { 112 | 113 | return node.children.map(child => { 114 | 115 | applyParameters(ast, walk, child) 116 | if (child.children && child.children.length !== 0) { 117 | 118 | if (ast.ruleNames[child.ruleIndex] === 'statement' && walk.statements > 1) { 119 | 120 | walk.newLine = true 121 | walk.statements++ 122 | walk.indent = 0 123 | 124 | } 125 | if (ast.ruleNames[child.ruleIndex] === 'query') { 126 | 127 | walk.newLine = true 128 | walk.indent = 1 129 | 130 | } 131 | if (indentTwoRules.includes(ast.ruleNames[child.ruleIndex])) { 132 | 133 | walk.newLine = true 134 | walk.indent = 2 135 | 136 | } 137 | if (indentThreeRules.includes(ast.ruleNames[child.ruleIndex])) { 138 | 139 | walk.newLine = true 140 | walk.indent = 3 141 | 142 | } 143 | return child.accept(walk) 144 | 145 | } else { 146 | 147 | const t = child.getText() 148 | if (t === '') return 149 | let space = '' 150 | if (walk.format) { 151 | 152 | space = walk.skipSpace ? '' : ' ' 153 | if (lineBreakWords.includes(t)) { 154 | 155 | if (t === 'FROM') { 156 | 157 | space = '\n' + pad(walk.indent - 1) 158 | 159 | } else { 160 | 161 | space = '\n' + pad(2) 162 | walk.indent = 2 163 | 164 | } 165 | 166 | } else if (walk.newLine) { 167 | 168 | walk.newLine = false 169 | space = '\n' + pad(walk.indent) 170 | 171 | } 172 | if (t === 'JOIN') { 173 | 174 | walk.newLine = true 175 | walk.indent++ 176 | 177 | } 178 | if (/^[.(=]$/.test(t)) { 179 | 180 | walk.skipSpace = true 181 | 182 | } else { 183 | 184 | walk.skipSpace = false 185 | 186 | } 187 | 188 | } 189 | if (/^[.,();=]$/.test(t)) { 190 | 191 | return t 192 | 193 | } 194 | return space + t 195 | 196 | } 197 | 198 | }) 199 | 200 | } 201 | 202 | }} 203 | 204 | walk.replacements = replacements 205 | var out = tree.accept(walk) 206 | return out.flat(Infinity).join('') 207 | 208 | } 209 | 210 | module.exports = replacer 211 | -------------------------------------------------------------------------------- /src/tests/config-good.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacements": { 3 | "time zone": "'Europe/London'", 4 | "with/partitions": 2, 5 | "function/timestamptostring/tz": "'US/West'" 6 | }, 7 | "topics": [ 8 | "order_total" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /src/tests/main.spec.js: -------------------------------------------------------------------------------- 1 | const capcon = require('capture-console') 2 | const fs = require('fs') 3 | const path = require('path') 4 | const expect = require('expect.js') 5 | const { 6 | run 7 | } = require('../main') 8 | process.env.QUERIES_CONFIG = 'src/tests/config-good.json' 9 | const config = require('../config') 10 | config.set('output', 'queries.ksql') 11 | 12 | function startCapture() { 13 | 14 | var output = '' 15 | capcon.startIntercept(process.stderr, function (stderr) { 16 | 17 | output += stderr 18 | 19 | }) 20 | return () => { 21 | 22 | capcon.stopIntercept(process.stderr) 23 | return output 24 | 25 | } 26 | 27 | } 28 | 29 | describe('main', async function () { 30 | 31 | describe('run', async function (done) { 32 | 33 | it('runs successfully with good input', async function () { 34 | 35 | config.set('queriesPath', path.join(__dirname, 'queries-good/')) 36 | const getCapture = startCapture() 37 | await run(config) 38 | const output = getCapture().toString().trim() 39 | expect(output).to.be('wrote queries to queries.ksql') 40 | fs.unlink('queries.ksql', () => {}) 41 | return true 42 | 43 | }) 44 | it('bad input generates useful error messages', async function () { 45 | 46 | config.set('queriesPath', path.join(__dirname, 'queries-bad/')) 47 | const getCapture = startCapture() 48 | await run(config) 49 | const output = getCapture().toString().trim() 50 | expect(output).to.contain('Error parsing file:') 51 | expect(output).to.contain('Error at column 96 on line 0') 52 | expect(output).to.contain('Error at column 22 on line 1') 53 | expect(output).to.contain("extraneous input '>' expecting {',', ')'}") 54 | expect(output).to.contain("mismatched input 'ON' expecting ';'") 55 | return true 56 | 57 | }) 58 | 59 | }) 60 | 61 | }) 62 | -------------------------------------------------------------------------------- /src/tests/queries-bad/bad-for-clause.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM foo WITH (TIMESTAMP='t2') AS 2 | SELECT * FROM bar b ON (a.id=b.id) 3 | WINDOW TUMBLING (size 10 seconds); 4 | -------------------------------------------------------------------------------- /src/tests/queries-bad/bad-struct.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM pageviews (viewtime BIGINT, user_id VARCHAR, page_id VARCHAR, `Properties` VARCHAR>) 2 | WITH (VALUE_FORMAT = 'JSON', 3 | KAFKA_TOPIC = 'my-pageviews-topic'); 4 | -------------------------------------------------------------------------------- /src/tests/queries-good/combined.ksql: -------------------------------------------------------------------------------- 1 | CREATE TABLE order_total WITH (VALUE_FORMAT='AVRO') 2 | AS SELECT 3 | u.order_id AS order_id, 4 | u.user_name AS username, 5 | u.email AS email, 6 | i.price * u.quantity AS total 7 | FROM 8 | orders_users u 9 | LEFT JOIN orders_items i ON (u.order_id = i.order_id) 10 | GROUP BY u.order_id 11 | ; -------------------------------------------------------------------------------- /src/tests/queries-good/item-root.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM items ( 2 | time VARCHAR, 3 | name VARCHAR, 4 | price BIGINT) 5 | WITH (KAFKA_TOPIC = 'items-in', 6 | VALUE_FORMAT='JSON', 7 | TIMESTAMP='rawTime', 8 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 9 | KEY = 'id'); 10 | -------------------------------------------------------------------------------- /src/tests/queries-good/one.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM orders_items WITH (VALUE_FORMAT='AVRO') 2 | AS SELECT 3 | o.id AS order_id, 4 | i.name AS item_name, 5 | i.price AS item_price 6 | FROM 7 | orders o 8 | JOIN items i ON (o.itemname=i.name) 9 | ; -------------------------------------------------------------------------------- /src/tests/queries-good/order-root.ksql: -------------------------------------------------------------------------------- 1 | CREATE STREAM orders ( 2 | id BIGINT, 3 | user BIGINT, 4 | item STRING, 5 | quantity INTEGER) 6 | WITH (KAFKA_TOPIC = 'orders-in', 7 | VALUE_FORMAT='JSON', 8 | TIMESTAMP='rawTime', 9 | TIMESTAMP_FORMAT='yyyy-MM-dd''T''HH:mm:ss.SSSz', 10 | KEY = 'id'); 11 | -------------------------------------------------------------------------------- /src/tests/queries-good/syntax-tests.ksql: -------------------------------------------------------------------------------- 1 | --- code coverage queries 2 | DROP STREAM IF EXISTS test DELETE TOPIC; 3 | DROP TABLE IF EXISTS test DELETE TOPIC; 4 | SELECT * FROM topic WINDOW TUMBLING (SIZE 1 HOUR); 5 | EXPLAIN foo; 6 | EXPLAIN SELECT foo->sub, avg(bar), CASE WHEN n < 1 THEN 'small' WHEN n >= 2 THEN 'large' ELSE 'medium' END AS size FROM top1 f LEFT JOIN top2 b ON (f.a=b.a) WHERE foo=1 AND bas IS NOT DISTINCT FROM time AT TIME ZONE 'Europe/London' AND bar IS NOT NULL AND age BETWEEN 9 AND 13 AND name NOT LIKE 'bob%' GROUP BY bar HAVING b.c > 1; 7 | SELECT * FROM pageviews LIMIT 5; 8 | SELECT localize(address->city, address->zip), ROWTIME AT TIME ZONE 'UTC' FROM pageviews LIMIT 5; 9 | SELECT * FROM pageviews 10 | WHERE ROWTIME >= 1510923225000 11 | AND ROWTIME <= 1510923228000 12 | EMIT CHANGES; 13 | LIST TOPICS; 14 | LIST QUERIES EXTENDED; 15 | LIST FUNCTIONS; 16 | LIST PROPERTIES; 17 | LIST STREAMS; 18 | LIST TABLES; 19 | LIST TABLES EXTENDED; 20 | LIST SOURCE CONNECTORS; 21 | SHOW SINK CONNECTORS; 22 | SHOW TOPICS; 23 | SHOW STREAMS; 24 | SHOW TABLES; 25 | SHOW PROPERTIES; 26 | SHOW FUNCTIONS; 27 | SHOW TABLES EXTENDED; 28 | SET 'variable'='text'; 29 | UNSET 'variable'; 30 | DESCRIBE EXTENDED test; 31 | DESCRIBE FUNCTION test; 32 | DESCRIBE CONNECTOR foo; 33 | TERMINATE foo; 34 | TERMINATE QUERY foo; 35 | RUN SCRIPT 'test'; 36 | CREATE TYPE foo AS STRUCT