diff --git a/build-tools-internal/src/main/groovy/elasticsearch.build-scan.gradle b/build-tools-internal/src/main/groovy/elasticsearch.build-scan.gradle index f0a7b1a6d0b1..c6930c2263ec 100644 --- a/build-tools-internal/src/main/groovy/elasticsearch.build-scan.gradle +++ b/build-tools-internal/src/main/groovy/elasticsearch.build-scan.gradle @@ -26,6 +26,10 @@ develocity { if (jenkinsUrl?.host?.endsWith('elastic.co') || jenkinsUrl?.host?.endsWith('elastic.dev') || System.getenv('BUILDKITE') == 'true') { publishing.onlyIf { true } server = 'https://gradle-enterprise.elastic.co' + } else { + publishing.onlyIf { + server.isPresent(); + } } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java index 23afcab7bec7..9cc98e79183c 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java @@ -71,7 +71,6 @@ public abstract class RestrictedBuildApiService implements BuildService> and <> an <>. -include::{es-ref-dir}/tab-widgets/esql/esql-getting-started-enrich-policy.asciidoc[tag=own-deployment] - +include::{es-ref-dir}/tab-widgets/esql/esql-getting-started-widget-enrich-policy.asciidoc[] After creating and executing a policy, you can use it with the `ENRICH` command: diff --git a/docs/reference/esql/processing-commands/lookup.asciidoc b/docs/reference/esql/processing-commands/lookup.asciidoc index 5507c6cc29d1..1944d243968a 100644 --- a/docs/reference/esql/processing-commands/lookup.asciidoc +++ b/docs/reference/esql/processing-commands/lookup.asciidoc @@ -27,7 +27,7 @@ adding the other fields from the `table` to the output. *Examples* // tag::examples[] -[source,console] +[source,console,id=esql-lookup-example] ---- POST /_query?format=txt { @@ -40,8 +40,8 @@ POST /_query?format=txt """, "tables": { "era": { - "author:keyword": ["Frank Herbert", "Peter F. Hamilton", "Vernor Vinge", "Alastair Reynolds", "James S.A. Corey"], - "era:keyword" : [ "The New Wave", "Diamond", "Diamond", "Diamond", "Hadron"] + "author": {"keyword": ["Frank Herbert", "Peter F. Hamilton", "Vernor Vinge", "Alastair Reynolds", "James S.A. Corey"]}, + "era": {"keyword": [ "The New Wave", "Diamond", "Diamond", "Diamond", "Hadron"]} } } } diff --git a/docs/reference/settings/security-settings.asciidoc b/docs/reference/settings/security-settings.asciidoc index e0d01965479c..7dd9d0574638 100644 --- a/docs/reference/settings/security-settings.asciidoc +++ b/docs/reference/settings/security-settings.asciidoc @@ -23,7 +23,9 @@ For more information about creating and updating the {es} keystore, see ==== General security settings `xpack.security.enabled`:: (<>) -Defaults to `true`, which enables {es} {security-features} on the node. + +Defaults to `true`, which enables {es} {security-features} on the node. +This setting must be enabled to use Elasticsearch's authentication, +authorization and audit features. + + -- If set to `false`, {security-features} are disabled, which is not recommended. diff --git a/docs/reference/tab-widgets/esql/esql-getting-started-sample-data.asciidoc b/docs/reference/tab-widgets/esql/esql-getting-started-sample-data.asciidoc index 97f4859e012a..d9b08b7281f7 100644 --- a/docs/reference/tab-widgets/esql/esql-getting-started-sample-data.asciidoc +++ b/docs/reference/tab-widgets/esql/esql-getting-started-sample-data.asciidoc @@ -1,6 +1,6 @@ // tag::own-deployment[] -First, you'll need to ingest the sample data. In {kib}, open the main menu and select *Dev +First ingest some sample data. In {kib}, open the main menu and select *Dev Tools*. Run the following two requests: [source,console] diff --git a/modules/lang-painless/src/main/generated/whitelist-json/painless-score.json b/modules/lang-painless/src/main/generated/whitelist-json/painless-score.json index 56fe66d849b8..da9f7f7b6038 100644 --- a/modules/lang-painless/src/main/generated/whitelist-json/painless-score.json +++ b/modules/lang-painless/src/main/generated/whitelist-json/painless-score.json @@ -1 +1 @@ -{"name":"score","classes":[{"name":"String","imported":true,"constructors":[{"declaring":"String","parameters":[]}],"static_methods":[{"declaring":"String","name":"copyValueOf","return":"String","parameters":["char[]"]},{"declaring":"String","name":"copyValueOf","return":"String","parameters":["char[]","int","int"]},{"declaring":"String","name":"format","return":"String","parameters":["String","def[]"]},{"declaring":"String","name":"format","return":"String","parameters":["Locale","String","def[]"]},{"declaring":"String","name":"join","return":"String","parameters":["CharSequence","Iterable"]},{"declaring":"String","name":"valueOf","return":"String","parameters":["def"]}],"methods":[{"declaring":"CharSequence","name":"charAt","return":"char","parameters":["int"]},{"declaring":"CharSequence","name":"chars","return":"IntStream","parameters":[]},{"declaring":"String","name":"codePointAt","return":"int","parameters":["int"]},{"declaring":"String","name":"codePointBefore","return":"int","parameters":["int"]},{"declaring":"String","name":"codePointCount","return":"int","parameters":["int","int"]},{"declaring":"CharSequence","name":"codePoints","return":"IntStream","parameters":[]},{"declaring":"String","name":"compareTo","return":"int","parameters":["String"]},{"declaring":"String","name":"compareToIgnoreCase","return":"int","parameters":["String"]},{"declaring":"String","name":"concat","return":"String","parameters":["String"]},{"declaring":"String","name":"contains","return":"boolean","parameters":["CharSequence"]},{"declaring":"String","name":"contentEquals","return":"boolean","parameters":["CharSequence"]},{"declaring":null,"name":"decodeBase64","return":"String","parameters":[]},{"declaring":null,"name":"encodeBase64","return":"String","parameters":[]},{"declaring":"String","name":"endsWith","return":"boolean","parameters":["String"]},{"declaring":"Object","name":"equals","return":"boolean","parameters":["Object"]},{"declaring":"String","name":"equalsIgnoreCase","return":"boolean","parameters":["String"]},{"declaring":"String","name":"getChars","return":"void","parameters":["int","int","char[]","int"]},{"declaring":"Object","name":"hashCode","return":"int","parameters":[]},{"declaring":"String","name":"indexOf","return":"int","parameters":["String"]},{"declaring":"String","name":"indexOf","return":"int","parameters":["String","int"]},{"declaring":"String","name":"isEmpty","return":"boolean","parameters":[]},{"declaring":"String","name":"lastIndexOf","return":"int","parameters":["String"]},{"declaring":"String","name":"lastIndexOf","return":"int","parameters":["String","int"]},{"declaring":"CharSequence","name":"length","return":"int","parameters":[]},{"declaring":"String","name":"offsetByCodePoints","return":"int","parameters":["int","int"]},{"declaring":"String","name":"regionMatches","return":"boolean","parameters":["int","String","int","int"]},{"declaring":"String","name":"regionMatches","return":"boolean","parameters":["boolean","int","String","int","int"]},{"declaring":"String","name":"replace","return":"String","parameters":["CharSequence","CharSequence"]},{"declaring":null,"name":"replaceAll","return":"String","parameters":["Pattern","Function"]},{"declaring":null,"name":"replaceFirst","return":"String","parameters":["Pattern","Function"]},{"declaring":null,"name":"splitOnToken","return":"String[]","parameters":["String"]},{"declaring":null,"name":"splitOnToken","return":"String[]","parameters":["String","int"]},{"declaring":"String","name":"startsWith","return":"boolean","parameters":["String"]},{"declaring":"String","name":"startsWith","return":"boolean","parameters":["String","int"]},{"declaring":"CharSequence","name":"subSequence","return":"CharSequence","parameters":["int","int"]},{"declaring":"String","name":"substring","return":"String","parameters":["int"]},{"declaring":"String","name":"substring","return":"String","parameters":["int","int"]},{"declaring":"String","name":"toCharArray","return":"char[]","parameters":[]},{"declaring":"String","name":"toLowerCase","return":"String","parameters":[]},{"declaring":"String","name":"toLowerCase","return":"String","parameters":["Locale"]},{"declaring":"CharSequence","name":"toString","return":"String","parameters":[]},{"declaring":"String","name":"toUpperCase","return":"String","parameters":[]},{"declaring":"String","name":"toUpperCase","return":"String","parameters":["Locale"]},{"declaring":"String","name":"trim","return":"String","parameters":[]}],"static_fields":[],"fields":[]},{"name":"DenseVectorScriptDocValues","imported":true,"constructors":[],"static_methods":[],"methods":[{"declaring":"Collection","name":"add","return":"boolean","parameters":["def"]},{"declaring":"List","name":"add","return":"void","parameters":["int","def"]},{"declaring":"Collection","name":"addAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"addAll","return":"boolean","parameters":["int","Collection"]},{"declaring":null,"name":"any","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"asCollection","return":"Collection","parameters":[]},{"declaring":null,"name":"asList","return":"List","parameters":[]},{"declaring":"Collection","name":"clear","return":"void","parameters":[]},{"declaring":null,"name":"collect","return":"List","parameters":["Function"]},{"declaring":null,"name":"collect","return":"def","parameters":["Collection","Function"]},{"declaring":"Collection","name":"contains","return":"boolean","parameters":["def"]},{"declaring":"Collection","name":"containsAll","return":"boolean","parameters":["Collection"]},{"declaring":null,"name":"each","return":"def","parameters":["Consumer"]},{"declaring":null,"name":"eachWithIndex","return":"def","parameters":["ObjIntConsumer"]},{"declaring":"List","name":"equals","return":"boolean","parameters":["Object"]},{"declaring":null,"name":"every","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"find","return":"def","parameters":["Predicate"]},{"declaring":null,"name":"findAll","return":"List","parameters":["Predicate"]},{"declaring":null,"name":"findResult","return":"def","parameters":["Function"]},{"declaring":null,"name":"findResult","return":"def","parameters":["def","Function"]},{"declaring":null,"name":"findResults","return":"List","parameters":["Function"]},{"declaring":"Iterable","name":"forEach","return":"void","parameters":["Consumer"]},{"declaring":"List","name":"get","return":"def","parameters":["int"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String","Object"]},{"declaring":null,"name":"getLength","return":"int","parameters":[]},{"declaring":null,"name":"groupBy","return":"Map","parameters":["Function"]},{"declaring":"List","name":"hashCode","return":"int","parameters":[]},{"declaring":"List","name":"indexOf","return":"int","parameters":["def"]},{"declaring":"Collection","name":"isEmpty","return":"boolean","parameters":[]},{"declaring":"Iterable","name":"iterator","return":"Iterator","parameters":[]},{"declaring":null,"name":"join","return":"String","parameters":["String"]},{"declaring":"List","name":"lastIndexOf","return":"int","parameters":["def"]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":[]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":["int"]},{"declaring":"List","name":"remove","return":"def","parameters":["int"]},{"declaring":"Collection","name":"removeAll","return":"boolean","parameters":["Collection"]},{"declaring":"Collection","name":"removeIf","return":"boolean","parameters":["Predicate"]},{"declaring":"List","name":"replaceAll","return":"void","parameters":["UnaryOperator"]},{"declaring":"Collection","name":"retainAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"set","return":"def","parameters":["int","def"]},{"declaring":"Collection","name":"size","return":"int","parameters":[]},{"declaring":"List","name":"sort","return":"void","parameters":["Comparator"]},{"declaring":null,"name":"split","return":"List","parameters":["Predicate"]},{"declaring":"Collection","name":"spliterator","return":"Spliterator","parameters":[]},{"declaring":"Collection","name":"stream","return":"Stream","parameters":[]},{"declaring":"List","name":"subList","return":"List","parameters":["int","int"]},{"declaring":null,"name":"sum","return":"double","parameters":[]},{"declaring":null,"name":"sum","return":"double","parameters":["ToDoubleFunction"]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":[]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":["def[]"]},{"declaring":"Object","name":"toString","return":"String","parameters":[]}],"static_fields":[],"fields":[]},{"name":"VersionScriptDocValues","imported":true,"constructors":[],"static_methods":[],"methods":[{"declaring":"Collection","name":"add","return":"boolean","parameters":["def"]},{"declaring":"List","name":"add","return":"void","parameters":["int","def"]},{"declaring":"Collection","name":"addAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"addAll","return":"boolean","parameters":["int","Collection"]},{"declaring":null,"name":"any","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"asCollection","return":"Collection","parameters":[]},{"declaring":null,"name":"asList","return":"List","parameters":[]},{"declaring":"Collection","name":"clear","return":"void","parameters":[]},{"declaring":null,"name":"collect","return":"List","parameters":["Function"]},{"declaring":null,"name":"collect","return":"def","parameters":["Collection","Function"]},{"declaring":"Collection","name":"contains","return":"boolean","parameters":["def"]},{"declaring":"Collection","name":"containsAll","return":"boolean","parameters":["Collection"]},{"declaring":null,"name":"each","return":"def","parameters":["Consumer"]},{"declaring":null,"name":"eachWithIndex","return":"def","parameters":["ObjIntConsumer"]},{"declaring":"List","name":"equals","return":"boolean","parameters":["Object"]},{"declaring":null,"name":"every","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"find","return":"def","parameters":["Predicate"]},{"declaring":null,"name":"findAll","return":"List","parameters":["Predicate"]},{"declaring":null,"name":"findResult","return":"def","parameters":["Function"]},{"declaring":null,"name":"findResult","return":"def","parameters":["def","Function"]},{"declaring":null,"name":"findResults","return":"List","parameters":["Function"]},{"declaring":"Iterable","name":"forEach","return":"void","parameters":["Consumer"]},{"declaring":"VersionScriptDocValues","name":"get","return":"String","parameters":["int"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String","Object"]},{"declaring":null,"name":"getLength","return":"int","parameters":[]},{"declaring":"VersionScriptDocValues","name":"getValue","return":"String","parameters":[]},{"declaring":null,"name":"groupBy","return":"Map","parameters":["Function"]},{"declaring":"List","name":"hashCode","return":"int","parameters":[]},{"declaring":"List","name":"indexOf","return":"int","parameters":["def"]},{"declaring":"Collection","name":"isEmpty","return":"boolean","parameters":[]},{"declaring":"Iterable","name":"iterator","return":"Iterator","parameters":[]},{"declaring":null,"name":"join","return":"String","parameters":["String"]},{"declaring":"List","name":"lastIndexOf","return":"int","parameters":["def"]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":[]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":["int"]},{"declaring":"List","name":"remove","return":"def","parameters":["int"]},{"declaring":"Collection","name":"removeAll","return":"boolean","parameters":["Collection"]},{"declaring":"Collection","name":"removeIf","return":"boolean","parameters":["Predicate"]},{"declaring":"List","name":"replaceAll","return":"void","parameters":["UnaryOperator"]},{"declaring":"Collection","name":"retainAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"set","return":"def","parameters":["int","def"]},{"declaring":"Collection","name":"size","return":"int","parameters":[]},{"declaring":"List","name":"sort","return":"void","parameters":["Comparator"]},{"declaring":null,"name":"split","return":"List","parameters":["Predicate"]},{"declaring":"Collection","name":"spliterator","return":"Spliterator","parameters":[]},{"declaring":"Collection","name":"stream","return":"Stream","parameters":[]},{"declaring":"List","name":"subList","return":"List","parameters":["int","int"]},{"declaring":null,"name":"sum","return":"double","parameters":[]},{"declaring":null,"name":"sum","return":"double","parameters":["ToDoubleFunction"]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":[]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":["def[]"]},{"declaring":"Object","name":"toString","return":"String","parameters":[]}],"static_fields":[],"fields":[]}],"imported_methods":[{"declaring":null,"name":"saturation","return":"double","parameters":["double","double"]},{"declaring":null,"name":"sigmoid","return":"double","parameters":["double","double","double"]}],"class_bindings":[{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$CosineSimilarity","name":"cosineSimilarity","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.util.List","java.lang.String"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayDateExp","name":"decayDateExp","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.script.JodaCompatibleZonedDateTime"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayDateGauss","name":"decayDateGauss","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.script.JodaCompatibleZonedDateTime"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayDateLinear","name":"decayDateLinear","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.script.JodaCompatibleZonedDateTime"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayGeoExp","name":"decayGeoExp","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.common.geo.GeoPoint"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayGeoGauss","name":"decayGeoGauss","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.common.geo.GeoPoint"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayGeoLinear","name":"decayGeoLinear","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.common.geo.GeoPoint"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayNumericExp","name":"decayNumericExp","return":"double","read_only":4,"parameters":["double","double","double","double","double"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayNumericGauss","name":"decayNumericGauss","return":"double","read_only":4,"parameters":["double","double","double","double","double"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayNumericLinear","name":"decayNumericLinear","return":"double","read_only":4,"parameters":["double","double","double","double","double"]},{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$DotProduct","name":"dotProduct","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.util.List","java.lang.String"]},{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$L1Norm","name":"l1norm","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.util.List","java.lang.String"]},{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$L2Norm","name":"l2norm","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.util.List","java.lang.String"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$RandomScoreDoc","name":"randomScore","return":"double","read_only":2,"parameters":["org.elasticsearch.script.ScoreScript","int"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$RandomScoreField","name":"randomScore","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","int","java.lang.String"]}],"instance_bindings":[]} +{"name":"score","classes":[{"name":"String","imported":true,"constructors":[{"declaring":"String","parameters":[]}],"static_methods":[{"declaring":"String","name":"copyValueOf","return":"String","parameters":["char[]"]},{"declaring":"String","name":"copyValueOf","return":"String","parameters":["char[]","int","int"]},{"declaring":"String","name":"format","return":"String","parameters":["String","def[]"]},{"declaring":"String","name":"format","return":"String","parameters":["Locale","String","def[]"]},{"declaring":"String","name":"join","return":"String","parameters":["CharSequence","Iterable"]},{"declaring":"String","name":"valueOf","return":"String","parameters":["def"]}],"methods":[{"declaring":"CharSequence","name":"charAt","return":"char","parameters":["int"]},{"declaring":"CharSequence","name":"chars","return":"IntStream","parameters":[]},{"declaring":"String","name":"codePointAt","return":"int","parameters":["int"]},{"declaring":"String","name":"codePointBefore","return":"int","parameters":["int"]},{"declaring":"String","name":"codePointCount","return":"int","parameters":["int","int"]},{"declaring":"CharSequence","name":"codePoints","return":"IntStream","parameters":[]},{"declaring":"String","name":"compareTo","return":"int","parameters":["String"]},{"declaring":"String","name":"compareToIgnoreCase","return":"int","parameters":["String"]},{"declaring":"String","name":"concat","return":"String","parameters":["String"]},{"declaring":"String","name":"contains","return":"boolean","parameters":["CharSequence"]},{"declaring":"String","name":"contentEquals","return":"boolean","parameters":["CharSequence"]},{"declaring":null,"name":"decodeBase64","return":"String","parameters":[]},{"declaring":null,"name":"encodeBase64","return":"String","parameters":[]},{"declaring":"String","name":"endsWith","return":"boolean","parameters":["String"]},{"declaring":"Object","name":"equals","return":"boolean","parameters":["Object"]},{"declaring":"String","name":"equalsIgnoreCase","return":"boolean","parameters":["String"]},{"declaring":"String","name":"getChars","return":"void","parameters":["int","int","char[]","int"]},{"declaring":"Object","name":"hashCode","return":"int","parameters":[]},{"declaring":"String","name":"indexOf","return":"int","parameters":["String"]},{"declaring":"String","name":"indexOf","return":"int","parameters":["String","int"]},{"declaring":"String","name":"isEmpty","return":"boolean","parameters":[]},{"declaring":"String","name":"lastIndexOf","return":"int","parameters":["String"]},{"declaring":"String","name":"lastIndexOf","return":"int","parameters":["String","int"]},{"declaring":"CharSequence","name":"length","return":"int","parameters":[]},{"declaring":"String","name":"offsetByCodePoints","return":"int","parameters":["int","int"]},{"declaring":"String","name":"regionMatches","return":"boolean","parameters":["int","String","int","int"]},{"declaring":"String","name":"regionMatches","return":"boolean","parameters":["boolean","int","String","int","int"]},{"declaring":"String","name":"replace","return":"String","parameters":["CharSequence","CharSequence"]},{"declaring":null,"name":"replaceAll","return":"String","parameters":["Pattern","Function"]},{"declaring":null,"name":"replaceFirst","return":"String","parameters":["Pattern","Function"]},{"declaring":null,"name":"splitOnToken","return":"String[]","parameters":["String"]},{"declaring":null,"name":"splitOnToken","return":"String[]","parameters":["String","int"]},{"declaring":"String","name":"startsWith","return":"boolean","parameters":["String"]},{"declaring":"String","name":"startsWith","return":"boolean","parameters":["String","int"]},{"declaring":"CharSequence","name":"subSequence","return":"CharSequence","parameters":["int","int"]},{"declaring":"String","name":"substring","return":"String","parameters":["int"]},{"declaring":"String","name":"substring","return":"String","parameters":["int","int"]},{"declaring":"String","name":"toCharArray","return":"char[]","parameters":[]},{"declaring":"String","name":"toLowerCase","return":"String","parameters":[]},{"declaring":"String","name":"toLowerCase","return":"String","parameters":["Locale"]},{"declaring":"CharSequence","name":"toString","return":"String","parameters":[]},{"declaring":"String","name":"toUpperCase","return":"String","parameters":[]},{"declaring":"String","name":"toUpperCase","return":"String","parameters":["Locale"]},{"declaring":"String","name":"trim","return":"String","parameters":[]}],"static_fields":[],"fields":[]},{"name":"DenseVectorScriptDocValues","imported":true,"constructors":[],"static_methods":[],"methods":[{"declaring":"Collection","name":"add","return":"boolean","parameters":["def"]},{"declaring":"List","name":"add","return":"void","parameters":["int","def"]},{"declaring":"Collection","name":"addAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"addAll","return":"boolean","parameters":["int","Collection"]},{"declaring":null,"name":"any","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"asCollection","return":"Collection","parameters":[]},{"declaring":null,"name":"asList","return":"List","parameters":[]},{"declaring":"Collection","name":"clear","return":"void","parameters":[]},{"declaring":null,"name":"collect","return":"List","parameters":["Function"]},{"declaring":null,"name":"collect","return":"def","parameters":["Collection","Function"]},{"declaring":"Collection","name":"contains","return":"boolean","parameters":["def"]},{"declaring":"Collection","name":"containsAll","return":"boolean","parameters":["Collection"]},{"declaring":null,"name":"each","return":"def","parameters":["Consumer"]},{"declaring":null,"name":"eachWithIndex","return":"def","parameters":["ObjIntConsumer"]},{"declaring":"List","name":"equals","return":"boolean","parameters":["Object"]},{"declaring":null,"name":"every","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"find","return":"def","parameters":["Predicate"]},{"declaring":null,"name":"findAll","return":"List","parameters":["Predicate"]},{"declaring":null,"name":"findResult","return":"def","parameters":["Function"]},{"declaring":null,"name":"findResult","return":"def","parameters":["def","Function"]},{"declaring":null,"name":"findResults","return":"List","parameters":["Function"]},{"declaring":"Iterable","name":"forEach","return":"void","parameters":["Consumer"]},{"declaring":"List","name":"get","return":"def","parameters":["int"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String","Object"]},{"declaring":null,"name":"getLength","return":"int","parameters":[]},{"declaring":null,"name":"groupBy","return":"Map","parameters":["Function"]},{"declaring":"List","name":"hashCode","return":"int","parameters":[]},{"declaring":"List","name":"indexOf","return":"int","parameters":["def"]},{"declaring":"Collection","name":"isEmpty","return":"boolean","parameters":[]},{"declaring":"Iterable","name":"iterator","return":"Iterator","parameters":[]},{"declaring":null,"name":"join","return":"String","parameters":["String"]},{"declaring":"List","name":"lastIndexOf","return":"int","parameters":["def"]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":[]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":["int"]},{"declaring":"List","name":"remove","return":"def","parameters":["int"]},{"declaring":"Collection","name":"removeAll","return":"boolean","parameters":["Collection"]},{"declaring":"Collection","name":"removeIf","return":"boolean","parameters":["Predicate"]},{"declaring":"List","name":"replaceAll","return":"void","parameters":["UnaryOperator"]},{"declaring":"Collection","name":"retainAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"set","return":"def","parameters":["int","def"]},{"declaring":"Collection","name":"size","return":"int","parameters":[]},{"declaring":"List","name":"sort","return":"void","parameters":["Comparator"]},{"declaring":null,"name":"split","return":"List","parameters":["Predicate"]},{"declaring":"Collection","name":"spliterator","return":"Spliterator","parameters":[]},{"declaring":"Collection","name":"stream","return":"Stream","parameters":[]},{"declaring":"List","name":"subList","return":"List","parameters":["int","int"]},{"declaring":null,"name":"sum","return":"double","parameters":[]},{"declaring":null,"name":"sum","return":"double","parameters":["ToDoubleFunction"]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":[]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":["def[]"]},{"declaring":"Object","name":"toString","return":"String","parameters":[]}],"static_fields":[],"fields":[]},{"name":"VersionScriptDocValues","imported":true,"constructors":[],"static_methods":[],"methods":[{"declaring":"Collection","name":"add","return":"boolean","parameters":["def"]},{"declaring":"List","name":"add","return":"void","parameters":["int","def"]},{"declaring":"Collection","name":"addAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"addAll","return":"boolean","parameters":["int","Collection"]},{"declaring":null,"name":"any","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"asCollection","return":"Collection","parameters":[]},{"declaring":null,"name":"asList","return":"List","parameters":[]},{"declaring":"Collection","name":"clear","return":"void","parameters":[]},{"declaring":null,"name":"collect","return":"List","parameters":["Function"]},{"declaring":null,"name":"collect","return":"def","parameters":["Collection","Function"]},{"declaring":"Collection","name":"contains","return":"boolean","parameters":["def"]},{"declaring":"Collection","name":"containsAll","return":"boolean","parameters":["Collection"]},{"declaring":null,"name":"each","return":"def","parameters":["Consumer"]},{"declaring":null,"name":"eachWithIndex","return":"def","parameters":["ObjIntConsumer"]},{"declaring":"List","name":"equals","return":"boolean","parameters":["Object"]},{"declaring":null,"name":"every","return":"boolean","parameters":["Predicate"]},{"declaring":null,"name":"find","return":"def","parameters":["Predicate"]},{"declaring":null,"name":"findAll","return":"List","parameters":["Predicate"]},{"declaring":null,"name":"findResult","return":"def","parameters":["Function"]},{"declaring":null,"name":"findResult","return":"def","parameters":["def","Function"]},{"declaring":null,"name":"findResults","return":"List","parameters":["Function"]},{"declaring":"Iterable","name":"forEach","return":"void","parameters":["Consumer"]},{"declaring":"VersionScriptDocValues","name":"get","return":"String","parameters":["int"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String"]},{"declaring":null,"name":"getByPath","return":"Object","parameters":["String","Object"]},{"declaring":null,"name":"getLength","return":"int","parameters":[]},{"declaring":"VersionScriptDocValues","name":"getValue","return":"String","parameters":[]},{"declaring":null,"name":"groupBy","return":"Map","parameters":["Function"]},{"declaring":"List","name":"hashCode","return":"int","parameters":[]},{"declaring":"List","name":"indexOf","return":"int","parameters":["def"]},{"declaring":"Collection","name":"isEmpty","return":"boolean","parameters":[]},{"declaring":"Iterable","name":"iterator","return":"Iterator","parameters":[]},{"declaring":null,"name":"join","return":"String","parameters":["String"]},{"declaring":"List","name":"lastIndexOf","return":"int","parameters":["def"]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":[]},{"declaring":"List","name":"listIterator","return":"ListIterator","parameters":["int"]},{"declaring":"List","name":"remove","return":"def","parameters":["int"]},{"declaring":"Collection","name":"removeAll","return":"boolean","parameters":["Collection"]},{"declaring":"Collection","name":"removeIf","return":"boolean","parameters":["Predicate"]},{"declaring":"List","name":"replaceAll","return":"void","parameters":["UnaryOperator"]},{"declaring":"Collection","name":"retainAll","return":"boolean","parameters":["Collection"]},{"declaring":"List","name":"set","return":"def","parameters":["int","def"]},{"declaring":"Collection","name":"size","return":"int","parameters":[]},{"declaring":"List","name":"sort","return":"void","parameters":["Comparator"]},{"declaring":null,"name":"split","return":"List","parameters":["Predicate"]},{"declaring":"Collection","name":"spliterator","return":"Spliterator","parameters":[]},{"declaring":"Collection","name":"stream","return":"Stream","parameters":[]},{"declaring":"List","name":"subList","return":"List","parameters":["int","int"]},{"declaring":null,"name":"sum","return":"double","parameters":[]},{"declaring":null,"name":"sum","return":"double","parameters":["ToDoubleFunction"]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":[]},{"declaring":"Collection","name":"toArray","return":"def[]","parameters":["def[]"]},{"declaring":"Object","name":"toString","return":"String","parameters":[]}],"static_fields":[],"fields":[]}],"imported_methods":[{"declaring":null,"name":"saturation","return":"double","parameters":["double","double"]},{"declaring":null,"name":"sigmoid","return":"double","parameters":["double","double","double"]}],"class_bindings":[{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$CosineSimilarity","name":"cosineSimilarity","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.lang.Object","java.lang.String"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayDateExp","name":"decayDateExp","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.script.JodaCompatibleZonedDateTime"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayDateGauss","name":"decayDateGauss","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.script.JodaCompatibleZonedDateTime"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayDateLinear","name":"decayDateLinear","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.script.JodaCompatibleZonedDateTime"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayGeoExp","name":"decayGeoExp","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.common.geo.GeoPoint"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayGeoGauss","name":"decayGeoGauss","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.common.geo.GeoPoint"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayGeoLinear","name":"decayGeoLinear","return":"double","read_only":4,"parameters":["java.lang.String","java.lang.String","java.lang.String","double","org.elasticsearch.common.geo.GeoPoint"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayNumericExp","name":"decayNumericExp","return":"double","read_only":4,"parameters":["double","double","double","double","double"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayNumericGauss","name":"decayNumericGauss","return":"double","read_only":4,"parameters":["double","double","double","double","double"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$DecayNumericLinear","name":"decayNumericLinear","return":"double","read_only":4,"parameters":["double","double","double","double","double"]},{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$DotProduct","name":"dotProduct","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.lang.Object","java.lang.String"]},{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$L1Norm","name":"l1norm","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.lang.Object","java.lang.String"]},{"declaring":"org.elasticsearch.script.VectorScoreScriptUtils$L2Norm","name":"l2norm","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","java.lang.Object","java.lang.String"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$RandomScoreDoc","name":"randomScore","return":"double","read_only":2,"parameters":["org.elasticsearch.script.ScoreScript","int"]},{"declaring":"org.elasticsearch.script.ScoreScriptUtils$RandomScoreField","name":"randomScore","return":"double","read_only":3,"parameters":["org.elasticsearch.script.ScoreScript","int","java.lang.String"]}],"instance_bindings":[]} diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.score.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.score.txt index e1769d28e226..b0506e7aa677 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.score.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.score.txt @@ -27,9 +27,9 @@ static_import { double decayDateLinear(String, String, String, double, ZonedDateTime) bound_to org.elasticsearch.script.ScoreScriptUtils$DecayDateLinear double decayDateExp(String, String, String, double, ZonedDateTime) bound_to org.elasticsearch.script.ScoreScriptUtils$DecayDateExp double decayDateGauss(String, String, String, double, ZonedDateTime) bound_to org.elasticsearch.script.ScoreScriptUtils$DecayDateGauss - double l1norm(org.elasticsearch.script.ScoreScript, List, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$L1Norm - double l2norm(org.elasticsearch.script.ScoreScript, List, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$L2Norm - double cosineSimilarity(org.elasticsearch.script.ScoreScript, List, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$CosineSimilarity - double dotProduct(org.elasticsearch.script.ScoreScript, List, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$DotProduct + double l1norm(org.elasticsearch.script.ScoreScript, Object, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$L1Norm + double l2norm(org.elasticsearch.script.ScoreScript, Object, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$L2Norm + double cosineSimilarity(org.elasticsearch.script.ScoreScript, Object, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$CosineSimilarity + double dotProduct(org.elasticsearch.script.ScoreScript, Object, String) bound_to org.elasticsearch.script.VectorScoreScriptUtils$DotProduct } diff --git a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/145_dense_vector_byte_basic.yml b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/145_dense_vector_byte_basic.yml index 6ac4ba01c34e..4eb8df25c27b 100644 --- a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/145_dense_vector_byte_basic.yml +++ b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/145_dense_vector_byte_basic.yml @@ -77,7 +77,35 @@ setup: - match: {hits.hits.2._id: "1"} - match: {hits.hits.2._score: 1632.0} +--- +"Dot Product hexidecimal": + - requires: + cluster_features: "gte_v8.14.1" + reason: "support for hexidecimal byte vectors added in 8.14" + - do: + headers: + Content-Type: application/json + search: + rest_total_hits_as_int: true + body: + query: + script_score: + query: {match_all: {} } + script: + source: "dotProduct(params.query_vector, 'vector')" + params: + query_vector: "006ff30e84" + - match: {hits.total: 3} + + - match: {hits.hits.0._id: "2"} + - match: {hits.hits.0._score: 28732.0} + + - match: {hits.hits.1._id: "3"} + - match: {hits.hits.1._score: 17439.0} + + - match: {hits.hits.2._id: "1"} + - match: {hits.hits.2._score: 1632.0} --- "Cosine Similarity": - do: @@ -108,6 +136,39 @@ setup: - gte: {hits.hits.2._score: 0.509} - lte: {hits.hits.2._score: 0.512} +--- +"Cosine Similarity hexidecimal": + - requires: + cluster_features: "gte_v8.14.1" + reason: "support for hexidecimal byte vectors added in 8.14" + - do: + headers: + Content-Type: application/json + search: + rest_total_hits_as_int: true + body: + query: + script_score: + query: {match_all: {} } + script: + source: "cosineSimilarity(params.query_vector, 'vector')" + params: + query_vector: "006ff30e84" + + - match: {hits.total: 3} + + - match: {hits.hits.0._id: "2"} + - gte: {hits.hits.0._score: 0.995} + - lte: {hits.hits.0._score: 0.998} + + - match: {hits.hits.1._id: "3"} + - gte: {hits.hits.1._score: 0.829} + - lte: {hits.hits.1._score: 0.832} + + - match: {hits.hits.2._id: "1"} + - gte: {hits.hits.2._score: 0.509} + - lte: {hits.hits.2._score: 0.512} + --- "Cosine similarity with indexed vector": - do: diff --git a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/155_dense_vector_byte_l1l2.yml b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/155_dense_vector_byte_l1l2.yml index c3d008ea69d0..46075c5db744 100644 --- a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/155_dense_vector_byte_l1l2.yml +++ b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/155_dense_vector_byte_l1l2.yml @@ -70,6 +70,35 @@ setup: - gte: {hits.hits.2._score: 29.0} --- +"L1 norm hexidecimal": + - requires: + cluster_features: "gte_v8.14.1" + reason: "support for hexidecimal byte vectors added in 8.14" + - do: + headers: + Content-Type: application/json + search: + rest_total_hits_as_int: true + body: + query: + script_score: + query: {match_all: {} } + script: + source: "l1norm(params.query_vector, 'my_dense_vector')" + params: + query_vector: "006ff30e84" + + - match: {hits.total: 3} + + - match: {hits.hits.0._id: "1"} + - match: {hits.hits.0._score: 246.0} + + - match: {hits.hits.1._id: "3"} + - match: {hits.hits.1._score: 117.0} + + - match: {hits.hits.2._id: "2"} + - gte: {hits.hits.2._score: 29.0} +--- "L2 norm": - do: headers: @@ -95,6 +124,38 @@ setup: - gte: {hits.hits.1._score: 94.407} - lte: {hits.hits.1._score: 94.41} + - match: {hits.hits.2._id: "2"} + - gte: {hits.hits.2._score: 15.263} + - lte: {hits.hits.2._score: 15.266} +--- +"L2 norm hexidecimal": + - requires: + cluster_features: "gte_v8.14.1" + reason: "support for hexidecimal byte vectors added in 8.14" + - do: + headers: + Content-Type: application/json + search: + rest_total_hits_as_int: true + body: + query: + script_score: + query: {match_all: {} } + script: + source: "l2norm(params.query_vector, 'my_dense_vector')" + params: + query_vector: "006ff30e84" + + - match: {hits.total: 3} + + - match: {hits.hits.0._id: "1"} + - gte: {hits.hits.0._score: 158.624} + - lte: {hits.hits.0._score: 158.627} + + - match: {hits.hits.1._id: "3"} + - gte: {hits.hits.1._score: 94.407} + - lte: {hits.hits.1._score: 94.41} + - match: {hits.hits.2._id: "2"} - gte: {hits.hits.2._score: 15.263} - lte: {hits.hits.2._score: 15.266} diff --git a/muted-tests.yml b/muted-tests.yml index d82c823f664b..dea7741715a7 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -59,9 +59,6 @@ tests: - class: org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvAppendTests method: testEvaluateBlockWithoutNulls {TestCase=, } issue: https://github.com/elastic/elasticsearch/issues/109409 -- class: "org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT" - issue: "https://github.com/elastic/elasticsearch/issues/109478" - method: "test {yaml=reference/esql/processing-commands/lookup/line_31}" # Examples: # diff --git a/qa/apm/build.gradle b/qa/apm/build.gradle deleted file mode 100644 index ff22334462fd..000000000000 --- a/qa/apm/build.gradle +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import org.elasticsearch.gradle.Architecture -import org.elasticsearch.gradle.VersionProperties -import org.elasticsearch.gradle.internal.info.BuildParams - -import static org.elasticsearch.gradle.internal.distribution.InternalElasticsearchDistributionTypes.DOCKER - -apply plugin: 'elasticsearch.standalone-rest-test' -apply plugin: 'elasticsearch.test.fixtures' -apply plugin: 'elasticsearch.internal-distribution-download' - -dockerCompose { - environment.put 'STACK_VERSION', BuildParams.snapshotBuild ? VersionProperties.elasticsearch : VersionProperties.elasticsearch + "-SNAPSHOT" -} - -elasticsearch_distributions { - docker { - type = DOCKER - architecture = Architecture.current() - version = VersionProperties.getElasticsearch() - failIfUnavailable = false // This ensures we skip this testing if Docker is unavailable - } -} - -tasks.named("preProcessFixture").configure { - dependsOn elasticsearch_distributions.matching { it.architecture == Architecture.current() } -} - -tasks.register("integTest", Test) { - outputs.doNotCacheIf('Build cache is disabled for Docker tests') { true } - maxParallelForks = '1' - include '**/*IT.class' -} - -tasks.named("check").configure { - dependsOn "integTest" -} diff --git a/qa/apm/config/elasticsearch/roles.yml b/qa/apm/config/elasticsearch/roles.yml deleted file mode 100644 index 91277fa8dd65..000000000000 --- a/qa/apm/config/elasticsearch/roles.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -apm_server: - cluster: ['manage_ilm', 'manage_security', 'manage_api_key'] - indices: - - names: ['apm-*', 'logs-apm*', 'metrics-apm*', 'traces-apm*'] - privileges: ['write', 'create_index', 'manage', 'manage_ilm'] - applications: - - application: 'apm' - privileges: ['sourcemap:write', 'event:write', 'config_agent:read'] - resources: '*' -beats: - cluster: ['manage_index_templates', 'monitor', 'manage_ingest_pipelines', 'manage_ilm', 'manage_security', 'manage_api_key'] - indices: - - names: ['filebeat-*', 'shrink-filebeat-*'] - privileges: ['all'] -filebeat: - cluster: ['manage_index_templates', 'monitor', 'manage_ingest_pipelines', 'manage_ilm'] - indices: - - names: ['filebeat-*', 'shrink-filebeat-*'] - privileges: ['all'] -heartbeat: - cluster: ['manage_index_templates', 'monitor', 'manage_ingest_pipelines', 'manage_ilm'] - indices: - - names: ['heartbeat-*', 'shrink-heartbeat-*'] - privileges: ['all'] -metricbeat: - cluster: ['manage_index_templates', 'monitor', 'manage_ingest_pipelines', 'manage_ilm'] - indices: - - names: ['metricbeat-*', 'shrink-metricbeat-*'] - privileges: ['all'] -opbeans: - indices: - - names: ['opbeans-*'] - privileges: ['write', 'read'] diff --git a/qa/apm/config/elasticsearch/service_tokens b/qa/apm/config/elasticsearch/service_tokens deleted file mode 100644 index 02c39a69bc9b..000000000000 --- a/qa/apm/config/elasticsearch/service_tokens +++ /dev/null @@ -1,2 +0,0 @@ -elastic/fleet-server/elastic-package-fleet-server-token:{PBKDF2_STRETCH}10000$PNiVyY96dHwRfoDszBvYPAz+mSLbC+NhtPh63dblDZU=$dAY1tXX1U5rXB+2Lt7m0L2LUNSb1q5nRaIqPNZTBxb8= -elastic/kibana/elastic-package-kibana-token:{PBKDF2_STRETCH}10000$wIEFHIIIZ2ap0D0iQsyw0MfB7YuFA1bHnXAmlCoL4Gg=$YxvIJnasjLZyDQZpmFBiJHdR/CGXd5BnVm013Jty6p0= diff --git a/qa/apm/config/elasticsearch/users b/qa/apm/config/elasticsearch/users deleted file mode 100644 index 4cc30a99d92f..000000000000 --- a/qa/apm/config/elasticsearch/users +++ /dev/null @@ -1,9 +0,0 @@ -admin:$2a$10$xiY0ZzOKmDDN1p3if4t4muUBwh2.bFHADoMRAWQgSClm4ZJ4132Y. -apm_server_user:$2a$10$iTy29qZaCSVn4FXlIjertuO8YfYVLCbvoUAJ3idaXfLRclg9GXdGG -apm_user_ro:$2a$10$hQfy2o2u33SapUClsx8NCuRMpQyHP9b2l4t3QqrBA.5xXN2S.nT4u -beats_user:$2a$10$LRpKi4/Q3Qo4oIbiu26rH.FNIL4aOH4aj2Kwi58FkMo1z9FgJONn2 -filebeat_user:$2a$10$sFxIEX8tKyOYgsbJLbUhTup76ssvSD3L4T0H6Raaxg4ewuNr.lUFC -heartbeat_user:$2a$10$nKUGDr/V5ClfliglJhfy8.oEkjrDtklGQfhd9r9NoFqQeoNxr7uUK -kibana_system_user:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW -metricbeat_user:$2a$10$5PyTd121U2ZXnFk9NyqxPuLxdptKbB8nK5egt6M5/4xrKUkk.GReG -opbeans_user:$2a$10$iTy29qZaCSVn4FXlIjertuO8YfYVLCbvoUAJ3idaXfLRclg9GXdGG diff --git a/qa/apm/config/elasticsearch/users_roles b/qa/apm/config/elasticsearch/users_roles deleted file mode 100644 index 629fe7392c12..000000000000 --- a/qa/apm/config/elasticsearch/users_roles +++ /dev/null @@ -1,13 +0,0 @@ -apm_server:apm_server_user -apm_system:apm_server_user -apm_user:apm_server_user,apm_user_ro -beats:beats_user -beats_system:beats_user,filebeat_user,heartbeat_user,metricbeat_user -filebeat:filebeat_user -heartbeat:heartbeat_user -ingest_admin:apm_server_user -kibana_system:kibana_system_user -kibana_user:apm_server_user,apm_user_ro,beats_user,filebeat_user,heartbeat_user,metricbeat_user,opbeans_user -metricbeat:metricbeat_user -opbeans:opbeans_user -superuser:admin diff --git a/qa/apm/config/kibana/kibana-8.yml b/qa/apm/config/kibana/kibana-8.yml deleted file mode 100644 index 4b3add76282d..000000000000 --- a/qa/apm/config/kibana/kibana-8.yml +++ /dev/null @@ -1,78 +0,0 @@ -xpack.fleet.packages: - - name: system - version: latest - - name: elastic_agent - version: latest - - name: apm - version: latest - - name: fleet_server - version: latest - -xpack.fleet.agentPolicies: - - name: Fleet Server + APM policy - id: fleet-server-apm-policy - description: Fleet server policy with APM and System logs and metrics enabled - namespace: default - is_default_fleet_server: true - is_managed: false - monitoring_enabled: - - logs - - metrics - package_policies: - - name: system-1 - package: - name: system - - name: apm-1 - package: - name: apm - inputs: - - type: apm - keep_enabled: true - vars: - - name: host - value: 0.0.0.0:8200 - frozen: true - - name: url - value: "${ELASTIC_APM_SERVER_URL}" - frozen: true - - name: enable_rum - value: true - frozen: true - - name: read_timeout - value: 1m - frozen: true - - name: shutdown_timeout - value: 2m - frozen: true - - name: write_timeout - value: 1m - frozen: true - - name: rum_allow_headers - value: - - x-custom-header - frozen: true - - name: secret_token - value: "${ELASTIC_APM_SECRET_TOKEN}" - frozen: true - - name: tls_enabled - value: ${ELASTIC_APM_TLS} - frozen: true - - name: tls_certificate - value: /usr/share/apmserver/config/certs/tls.crt - frozen: true - - name: tls_key - value: /usr/share/apmserver/config/certs/tls.key - frozen: true - - name: Fleet Server - package: - name: fleet_server - inputs: - - type: fleet-server - keep_enabled: true - vars: - - name: host - value: 0.0.0.0 - frozen: true - - name: port - value: 8220 - frozen: true diff --git a/qa/apm/docker-compose.yml b/qa/apm/docker-compose.yml deleted file mode 100644 index a3969479d091..000000000000 --- a/qa/apm/docker-compose.yml +++ /dev/null @@ -1,154 +0,0 @@ -version: "2.4" - -networks: - default: - name: apm-integration-testing - -services: - apmserver: - depends_on: - kibana: - condition: service_healthy - environment: - FLEET_ELASTICSEARCH_HOST: null - FLEET_SERVER_ELASTICSEARCH_INSECURE: "1" - FLEET_SERVER_ENABLE: "1" - FLEET_SERVER_HOST: 0.0.0.0 - FLEET_SERVER_INSECURE_HTTP: "1" - FLEET_SERVER_POLICY_ID: fleet-server-apm-policy - FLEET_SERVER_PORT: "8220" - FLEET_SERVER_SERVICE_TOKEN: AAEAAWVsYXN0aWMvZmxlZXQtc2VydmVyL2VsYXN0aWMtcGFja2FnZS1mbGVldC1zZXJ2ZXItdG9rZW46bmgtcFhoQzRRQ2FXbms2U0JySGlWQQ - KIBANA_FLEET_HOST: null - KIBANA_FLEET_SERVICE_TOKEN: AAEAAWVsYXN0aWMvZmxlZXQtc2VydmVyL2VsYXN0aWMtcGFja2FnZS1mbGVldC1zZXJ2ZXItdG9rZW46bmgtcFhoQzRRQ2FXbms2U0JySGlWQQ - KIBANA_FLEET_SETUP: "1" - healthcheck: - test: /bin/true - image: docker.elastic.co/beats/elastic-agent:${STACK_VERSION} - labels: - - co.elastic.apm.stack-version=${STACK_VERSION} - logging: - driver: json-file - options: - max-file: "5" - max-size: 2m - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ./scripts/tls/apmserver/cert.crt:/usr/share/apmserver/config/certs/tls.crt - - ./scripts/tls/apmserver/key.pem:/usr/share/apmserver/config/certs/tls.key - - elasticsearch: - environment: - - action.destructive_requires_name=false - - bootstrap.memory_lock=true - - cluster.name=docker-cluster - - cluster.routing.allocation.disk.threshold_enabled=false - - discovery.type=single-node - - ES_JAVA_OPTS=-Xms1g -Xmx1g - - indices.id_field_data.enabled=true - - ingest.geoip.downloader.enabled=false - - path.repo=/usr/share/elasticsearch/data/backups - - xpack.license.self_generated.type=trial - - xpack.monitoring.collection.enabled=true - - xpack.security.authc.anonymous.roles=remote_monitoring_collector - - xpack.security.authc.api_key.enabled=true - - xpack.security.authc.realms.file.file1.order=0 - - xpack.security.authc.realms.native.native1.order=1 - - xpack.security.authc.token.enabled=true - - xpack.security.enabled=true - # APM specific settings. We don't configure `secret_key` because Kibana is configured with a blank key - - telemetry.tracing.enabled=true - - telemetry.agent.server_url=http://apmserver:8200 - # Send traces to APM server aggressively - - telemetry.agent.metrics_interval=1s - # Record everything - - telemetry.agent.transaction_sample_rate=1 - - telemetry.agent.log_level=debug - healthcheck: - interval: 20s - retries: 10 - test: curl -s -k http://localhost:9200/_cluster/health | grep -vq '"status":"red"' - image: elasticsearch:test - labels: - - co.elastic.apm.stack-version=${STACK_VERSION} - - co.elastic.metrics/module=elasticsearch - - co.elastic.metrics/metricsets=node,node_stats - - co.elastic.metrics/hosts=http://$${data.host}:9200 - logging: - driver: json-file - options: - max-file: "5" - max-size: 2m - ports: - # - 127.0.0.1:9200:9200 - - "9200" - ulimits: - memlock: - hard: -1 - soft: -1 - volumes: - - ./config/elasticsearch/roles.yml:/usr/share/elasticsearch/config/roles.yml - - ./config/elasticsearch/users:/usr/share/elasticsearch/config/users - - ./config/elasticsearch/users_roles:/usr/share/elasticsearch/config/users_roles - - ./config/elasticsearch/service_tokens:/usr/share/elasticsearch/config/service_tokens - - kibana: - depends_on: - elasticsearch: - condition: service_healthy - environment: - ELASTICSEARCH_HOSTS: http://elasticsearch:9200 - ELASTICSEARCH_PASSWORD: changeme - ELASTICSEARCH_USERNAME: kibana_system_user - ELASTIC_APM_SECRET_TOKEN: "" - ELASTIC_APM_SERVER_URL: http://apmserver:8200 - ELASTIC_APM_TLS: "false" - SERVER_HOST: 0.0.0.0 - SERVER_NAME: kibana.example.org - STATUS_ALLOWANONYMOUS: "true" - TELEMETRY_ENABLED: "false" - XPACK_APM_SERVICEMAPENABLED: "true" - XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: fhjskloppd678ehkdfdlliverpoolfcr - XPACK_FLEET_AGENTS_ELASTICSEARCH_HOSTS: '["http://elasticsearch:9200"]' - # XPACK_FLEET_REGISTRYURL: https://epr-snapshot.elastic.co - XPACK_MONITORING_ENABLED: "true" - XPACK_REPORTING_ROLES_ENABLED: "false" - XPACK_SECURITY_ENCRYPTIONKEY: fhjskloppd678ehkdfdlliverpoolfcr - XPACK_SECURITY_LOGINASSISTANCEMESSAGE: Login details: `admin/changeme`. Further details [here](https://github.com/elastic/apm-integration-testing#logging-in). - XPACK_SECURITY_SESSION_IDLETIMEOUT: 1M - XPACK_SECURITY_SESSION_LIFESPAN: 3M - XPACK_XPACK_MAIN_TELEMETRY_ENABLED: "false" - healthcheck: - interval: 10s - retries: 30 - start_period: 10s - test: curl -s -k http://kibana:5601/api/status | grep -q 'All services are available' - image: docker.elastic.co/kibana/kibana:${STACK_VERSION} - labels: - - co.elastic.apm.stack-version=${STACK_VERSION} - logging: - driver: json-file - options: - max-file: "5" - max-size: 2m - # ports: - # - 127.0.0.1:5601:5601 - volumes: - - ./config/kibana/kibana-8.yml:/usr/share/kibana/config/kibana.yml - - # Rather than mess aroud with threads in the test, just run `curl` in a - # loop to generate traces with a known path - tracegenerator: - depends_on: - apmserver: - condition: service_healthy - elasticsearch: - condition: service_healthy - kibana: - condition: service_healthy - # Official curl image - image: curlimages/curl - command: /bin/sh -c "while true; do curl -s -k -u admin:changeme http://elasticsearch:9200/_nodes/stats >/dev/null ; sleep 3; done" - -volumes: - esdata: - driver: local diff --git a/qa/apm/scripts/tls/apm-server/cert.crt b/qa/apm/scripts/tls/apm-server/cert.crt deleted file mode 100644 index b2f9aa7b5d23..000000000000 --- a/qa/apm/scripts/tls/apm-server/cert.crt +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEpjCCAo4CCQDR9oXvJbopHjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDDAph -cG0tc2VydmVyMB4XDTE5MTExOTE1MjE0NVoXDTI5MTExNjE1MjE0NVowFTETMBEG -A1UEAwwKYXBtLXNlcnZlcjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -ANduj3tyeBIHj0Bf5aKMRImhRbkAaQ2p6T0WsHKlicd1P4/D5l783+vVsbwprRqR -qXAUsUWcUSYJXBX1qtC2MtKqi4xYUTAyQV5dgrMoCV+vtZY31SK4kolumd1vVMh+ -po+IwueLvLMFK1tQGIXlJblSDYVauIt5rp79IIhWOY/YpcQy9RaxykljTYTbPjLW -m3T92bow1nLh5GL3ThJEAkLO+hkJv9716+YRWYtPcojiGzpLjFgF50MoP4Lilm9U -r2tBnqpvb2PwE1kkly8DDBtcg+HM4tgGsbdWo2Pgp82ARV4DL+JlNJ+SVQZAmTbc -3LMwxnUJtuKMeh2rwb9HOyuONXfF1PiEzyDhAlabyS6toAGy1mlMAop1ClO1wV5O -Ayy47TeD6ziNyMKB7/XHdW4rb16K6j6EV27Bg2ZK6Vrfkwm3aRbpztfVRMX+HMUp -ktH+V2OwJoP7l7lzw/q8yMdopG57zRJa1dx8NWP/UKi8Ej+87DYyWJODiNHD7PM7 -9vfd47lNcWxw+p7ntEpnn6EeW2r7SlmfhtdIxL2DiTiKAq9Ktyi9cFnGnDfSDJST -T1G1vIDdG33Vt2Y5+wqzCGbYyMsAOaMdXZSeniXXFR4GX7iz+AGoKojBbmoo9VqP -mvbudNU+ysha4IJvTfOczJZgstxCXG+MXbEXFSgysImFAgMBAAEwDQYJKoZIhvcN -AQELBQADggIBAFh2YxRT6PaAXDq38rm25I91fCP9PzVPDuIkn9wl85e7avuh6FZi -R0nQG6+lB1i8XSm9UMl9+ISjE+EQqry6KB6mDsakGOsDuEUdZiw3sGJIUWQkQArB -ym5DqxKpeZBeVHBxnrEbQBV8s0j8uxd7X1E0ImfMKbKfNr/B5qPRXkREvydLWYvq -8yMcUPu1MiZFUgAGr9Py39kW3lbRPWZii/2bN8AB9h6gAhq5TiennfgJZsRiuSta -w/TmOcAuz4e/KPIzfvL/YCWbLyJ2vrIQeOc4N7jZfqMmLKgYCRyjI7+amfuyKPBW -J4psfJ0ssHdTxAUK65vghJ2s6FLvU3HoxzetZsJp5kj6CKYaFYkB4NkkYnlY8MP/ -T68oOmdYwwwrcBmDtZwoppRb5zhev5k3aykgZ/B/vqVJE9oIPkp/7wqEP1WqSiUe -AgyQBu8UN4ho2Rf6nZezZ4cjW/0WyhGOHQBFmwPI2MBGsQxF2PF4lKkJtaywIEm7 -4UsEQYK7Hf2J2OccWGvfo5HZ5tsSbuOGAf0bfHfaBQBsvzWet+TO6XX9VrWjnAKl -bH+mInmnd9v2oABFl9Djv/Cw+lEAxxkCTW+DcwdEFJREPab5xhQDEpQQ/Ef0ihvg -/ZtJQeoOYfrLN6K726QmoRWxvqxLyWK3gztcO1svHqr/cMt3ooLJEaqU ------END CERTIFICATE----- diff --git a/qa/apm/scripts/tls/apm-server/key.pem b/qa/apm/scripts/tls/apm-server/key.pem deleted file mode 100644 index 31208905f7d7..000000000000 --- a/qa/apm/scripts/tls/apm-server/key.pem +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDXbo97cngSB49A -X+WijESJoUW5AGkNqek9FrBypYnHdT+Pw+Ze/N/r1bG8Ka0akalwFLFFnFEmCVwV -9arQtjLSqouMWFEwMkFeXYKzKAlfr7WWN9UiuJKJbpndb1TIfqaPiMLni7yzBStb -UBiF5SW5Ug2FWriLea6e/SCIVjmP2KXEMvUWscpJY02E2z4y1pt0/dm6MNZy4eRi -904SRAJCzvoZCb/e9evmEVmLT3KI4hs6S4xYBedDKD+C4pZvVK9rQZ6qb29j8BNZ -JJcvAwwbXIPhzOLYBrG3VqNj4KfNgEVeAy/iZTSfklUGQJk23NyzMMZ1CbbijHod -q8G/RzsrjjV3xdT4hM8g4QJWm8kuraABstZpTAKKdQpTtcFeTgMsuO03g+s4jcjC -ge/1x3VuK29eiuo+hFduwYNmSula35MJt2kW6c7X1UTF/hzFKZLR/ldjsCaD+5e5 -c8P6vMjHaKRue80SWtXcfDVj/1CovBI/vOw2MliTg4jRw+zzO/b33eO5TXFscPqe -57RKZ5+hHltq+0pZn4bXSMS9g4k4igKvSrcovXBZxpw30gyUk09RtbyA3Rt91bdm -OfsKswhm2MjLADmjHV2Unp4l1xUeBl+4s/gBqCqIwW5qKPVaj5r27nTVPsrIWuCC -b03znMyWYLLcQlxvjF2xFxUoMrCJhQIDAQABAoICAQCfClIGsoUN2mLZBXLDw4W9 -jT+pyjHEEpHLtXphyO+kPlzER71Elq7AriveW24d1TcfNUeBulr2F6bR12FZX4i5 -mYoX/AND73Xusl4Q4Re6ej82PNWuIlCcAPi6Trxqn4VbJX2t7q1KBCDz8neIMZjd -7UNqFYV0Akr1uK1RuUYZebk21N+29139O8A4upp6cZCml9kq6W8HtNgkb6pFNcvt -gluELHxnn2mdmWVfwTEu+K1dJfTf7svB+m6Ys6qXWg9+wRzfehDj2JKQFsE9xaQk -dvItulIlZRvB28YXr/xxa6bKNtQc8NYej6sRSJNTu017RCDeumM3cLmeOfR4v59f -tkMWnFcA3ykmsaK2FiQyX+MoWvs5vdT7/yNIfz3a4MErcWg8z3FDbffKfbhgsb+2 -z4Ub6fIRKZykW2ajN7t0378bMmJ3rPT66QF40aNNeWasF3EHcwekDPpsHIBJoY4G -9aG6uTUmRkC+NGeP9HroxkvDo2NbXn8XGOEJS64rwsME3CsUi1A5ZY0XLTxYptH6 -X2TfC5oTmnsYB/wWqo26bTJc0bwDOueQWYap0aVtv3f/0tzueKepCbxdeG4ikA0U -2t3F+OUmoCZ5D0p+6zLvrTUPhPCFEynp+vGUvmbwozYi0NWzFyFqlvqRG1KLIVLG -ZRyTMYuZ/cWkv1SJYbEcaQKCAQEA/9HaJg2YACv7rx6/FesE/81u16OYTaahHngW -4M+5rT0+fNKYH/fYkwavQ/Gr6FSTls7F+8K9DVwoGLZRQ3t6epCXqGqX0uaY+iSH -O8eezXVnHzUaVE4KlwJY9xZ+K1iIf5zUb5hpaQI0jKS/igcxFAsutWiyenrz8eQp -MAycZmzkQMLbUsa1t6y0VaEaC4YMHyQ9ag2eMfqbG27plFQbYxllHXowGMFXPheY -xACwo5V5tJUgRP+HlrI4rf0vadMgVIKxVSUiqIzGREIkYrTAshFjkpHR5/R8s/kH -Xm8q2gdoJltBFJzA2B8MHXVi7mYDBlUmBoRKhzkl/TSray9j7wKCAQEA15VsNQZu -cZluboz/R4EDbEm1po2UBcNNiu/fgJ8BDUkLzJESIITY41fgvBbTun1fiuGeE+El -0o1w4hQhIiV1KAB44w69fJR0VELfMZiIcd8kd0sDgPPVrd1MzzKPZ9yg4mbEkCCO -V/EoTi8Ut27sMcl8059qm1qq7I5pzHwSziNa087m+5VdfmvJZJVipudngZ3QmRgU -KKcBhgFFSkncYezoq2XQfRcqkk0sORxDvsMmRInyHZh0l9zv46ihgTvErlCHtizV -V4HNO4OPz7FxUZ04iWSGZs4snu1cW2j+lbKuOkADveBYVmCcdZ3R0SH+A5skL0zG -tm6z0TNP/kFlywKCAQEA+lTdFu2od0qTADujG4yemL7rn2J8EEhlU86J/LXo6UiM -FFNz/5xltwIMkf00jqXswt9WR9W5cBBlQEFwZgu3v6YscebU6NE0k1sZZnshv8YK -AjTRrfusSzdF3YyKLFp3QAE0tHs9cz9wMsyojiYZdZa3v1dTh503h9YQI+/DQEuA -VIsZWfgPLEx5L231cZ9bz0GEQ3pN+nRUQdUYB0kCf8gC9YRy+lZ/y8gFeo9+SqVj -sj1XlY1DnkiKRGAEfJbYBTra0woCz1LqVTMwLdLY2adAe9XrxQKu4OJovpUkJrSm -yxnzJnt6DkLbdRxAki8K+LBsBGaCE67tqMhYkguOywKCAQAslEl77YiJFSEw2xcu -wg7jJZrahgxF5Mz0HgYporek96Xo91a4QsBWwqVGP7IoriRDo8P8eGJJ19Wv6lmv -pe9EBlT5HuMwD8K+adWde907Ltlrkad30vQsr8ZiUiI1Z/oc1wNuikzlAolDIZk3 -FUjiQrf9SsnQtj8CC7D1B/MbjVQK2I4LGCftLHzIv9tWiCNvOiMYhVIl1eMKwtiB -NCTOWx8B0lv6gf/boPm0FZQsrk4LfjsCw7PYc2dnvEcpYiKZqS1nDn5PShgWZm4m -lJrKNairQI5KU/gGJS8j9+ItMnW0tegQK4QY2IGCENCCXnUYacxhu46byuiEKggw -m3VhAoIBAQCQa90StsZHqZ+J83do3kpvD+O5nURPnckznC2WJgraW49k5vltnJTT -zkFTqHMLfmYwAz1o15sPCqlkMD+fEUzg6Hpzxm7dOUppkf5KFbD7AnsYU9U8LamJ -HaET7Dq5TpjG7uoaHZZjs7cCHcWu2E8nIezyAtZ+rbTg/qW7bYMAlJTkerznGuDU -v0hNzCr/81o5rbX0UhetcmKVOprUSWzfrw5ElLhAtzM7zivbZSnsOny8pC33FtQ5 -iQbVcNGUjfFCM95ZipxxN9z0FwxpJ1paCPGYA86u2olWl/VnVPqEj7WYzO8H5W2q -aXpWH6HVf6B10pQrWWwUAAHyqYS5bZkQ ------END PRIVATE KEY----- diff --git a/qa/apm/src/test/java/org/elasticsearch/telemetry/apm/ApmIT.java b/qa/apm/src/test/java/org/elasticsearch/telemetry/apm/ApmIT.java deleted file mode 100644 index 021d9f8d01bf..000000000000 --- a/qa/apm/src/test/java/org/elasticsearch/telemetry/apm/ApmIT.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.telemetry.apm; - -import org.elasticsearch.client.Request; -import org.elasticsearch.client.Response; -import org.elasticsearch.common.settings.SecureString; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.common.xcontent.support.XContentMapValues; -import org.elasticsearch.core.CheckedRunnable; -import org.elasticsearch.test.rest.ESRestTestCase; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; - -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasKey; -import static org.hamcrest.Matchers.not; - -/** - * Tests around Elasticsearch's tracing support using APM. - */ -public class ApmIT extends ESRestTestCase { - - private static final String DATA_STREAM = "traces-apm-default"; - - /** - * Check that if we send HTTP traffic to Elasticsearch, then traces are captured in APM server. The traces are generated in - * a separate Docker container, which continually fetches `/_nodes/stats`. We check for the following: - *
    - *
  • A transaction for the REST API call - *
  • A span for the task started by the REST call - *
  • A child span started by the above span - *
- *

This proves that the hierarchy of spans is being correctly captured. - */ - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/90308") - public void testCapturesTracesForHttpTraffic() throws Exception { - checkTracesDataStream(); - - assertTracesExist(); - } - - private void checkTracesDataStream() throws Exception { - assertBusy(() -> { - final Response response = performRequestTolerantly(new Request("GET", "/_data_stream/" + DATA_STREAM)); - assertOK(response); - }, 1, TimeUnit.MINUTES); - } - - private void assertTracesExist() throws Exception { - // First look for a transaction for the REST calls that we make via the `tracegenerator` Docker container - - final AtomicReference transactionId = new AtomicReference<>(); - assertBusy(() -> { - final Request tracesSearchRequest = new Request("GET", "/" + DATA_STREAM + "/_search"); - tracesSearchRequest.setJsonEntity(""" - { - "query": { - "match": { "transaction.name": "GET /_nodes/stats" } - } - }"""); - final Response tracesSearchResponse = performRequestTolerantly(tracesSearchRequest); - assertOK(tracesSearchResponse); - - final List> documents = getDocuments(tracesSearchResponse); - assertThat(documents, not(empty())); - - final Map tx = documents.get(0); - - check(tx, "http.request.method", "GET"); - check(tx, "http.response.status_code", 200); - check(tx, "labels.es_cluster_name", "docker-cluster"); - check(tx, "labels.http_request_headers_authorization", "[REDACTED]"); - check(tx, "span.kind", "SERVER"); - check(tx, "transaction.result", "HTTP 2xx"); - check(tx, "url.path", "/_nodes/stats"); - - final String txId = pluck(tx, "transaction.id"); - transactionId.set(txId); - }, 1, TimeUnit.MINUTES); - - // Then look for the task that the REST call starts - - final AtomicReference monitorNodeStatsSpanId = new AtomicReference<>(); - assertBusy(() -> { - final List> documents = searchByParentId(transactionId.get()); - assertThat(documents, not(empty())); - - final Map spansByName = documents.stream().collect(Collectors.toMap(d -> pluck(d, "span.name"), d -> d)); - - assertThat(spansByName, hasKey("cluster:monitor/nodes/stats")); - - @SuppressWarnings("unchecked") - final Map span = (Map) spansByName.get("cluster:monitor/nodes/stats"); - check(span, "span.kind", "INTERNAL"); - - final String spanId = pluck(span, "span.id"); - monitorNodeStatsSpanId.set(spanId); - }, 1, TimeUnit.MINUTES); - - // Finally look for the child task that the task above started - - assertBusy(() -> { - final List> documents = searchByParentId(monitorNodeStatsSpanId.get()); - assertThat(documents, not(empty())); - - final Map spansByName = documents.stream().collect(Collectors.toMap(d -> pluck(d, "span.name"), d -> d)); - - assertThat(spansByName, hasKey("cluster:monitor/nodes/stats[n]")); - }, 1, TimeUnit.MINUTES); - } - - @SuppressWarnings("unchecked") - private T pluck(Map map, String path) { - String[] parts = path.split("\\."); - - Object result = map; - - for (String part : parts) { - result = ((Map) result).get(part); - } - - return (T) result; - } - - private List> searchByParentId(String parentId) throws IOException { - final Request searchRequest = new Request("GET", "/" + DATA_STREAM + "/_search"); - searchRequest.setJsonEntity(""" - { - "query": { - "match": { "parent.id": "%s" } - } - }""".formatted(parentId)); - final Response response = performRequestTolerantly(searchRequest); - assertOK(response); - - return getDocuments(response); - } - - /** - * We don't need to clean up the cluster, particularly as we have Kibana and APM server using ES as well as our test, so declare - * that we need to preserve the cluster in order to prevent the usual cleanup logic from running (and inevitably failing). - */ - @Override - protected boolean preserveClusterUponCompletion() { - return true; - } - - /** - * Turns exceptions into assertion failures so that {@link #assertBusy(CheckedRunnable)} can still retry. - */ - private Response performRequestTolerantly(Request request) { - try { - return client().performRequest(request); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - /** - * Customizes the client settings to use the same username / password that is configured in Docke.r - */ - @Override - protected Settings restClientSettings() { - String token = basicAuthHeaderValue("admin", new SecureString("changeme".toCharArray())); - return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token).build(); - } - - /** - * Constructs the correct cluster address by looking up the dynamic port that Elasticsearch is exposed on. - */ - @Override - protected String getTestRestCluster() { - return "localhost:" + getProperty("test.fixtures.elasticsearch.tcp.9200"); - } - - @SuppressWarnings("unchecked") - private List> getDocuments(Response response) throws IOException { - final Map stringObjectMap = ESRestTestCase.entityAsMap(response); - return (List>) XContentMapValues.extractValue("hits.hits._source", stringObjectMap); - } - - private String getProperty(String key) { - String value = System.getProperty(key); - if (value == null) { - throw new IllegalStateException( - "Could not find system properties from test.fixtures. " - + "This test expects to run with the elasticsearch.test.fixtures Gradle plugin" - ); - } - return value; - } - - private void check(Map doc, String path, T expected) { - assertThat(pluck(doc, path), equalTo(expected)); - } -} diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java index 95178429317b..3a2200f15276 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java @@ -50,8 +50,9 @@ public class UpgradeWithOldIndexSettingsIT extends ParameterizedFullClusterResta public void testMapperDynamicIndexSetting() throws IOException { assumeTrue( - "Setting deprecated in 6.x, but remained in 7.x and is no longer defined in 8.x", - getOldClusterTestVersion().before("8.0.0") + "Setting deprecated in 6.x, but was disallowed/removed incorrectly in some 7.x versions and can only be set safely in 7.17.22. " + + "Setting can't be used in 8.x ", + getOldClusterTestVersion().before("8.0.0") && getOldClusterTestVersion().after("7.17.21") ); String indexName = "my-index"; if (isRunningAgainstOldCluster()) { diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java index 99cbef655693..0830c1b766a2 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java @@ -91,9 +91,13 @@ public class DenseVectorMappingUpdateIT extends AbstractRollingUpgradeTestCase { .startObject("properties") .startObject("embedding") .field("type", "dense_vector") + .field("index", "true") .field("dims", 4) + .field("similarity", "cosine") .startObject("index_options") .field("type", "hnsw") + .field("m", "16") + .field("ef_construction", "100") .endObject() .endObject() .endObject() @@ -109,7 +113,7 @@ public class DenseVectorMappingUpdateIT extends AbstractRollingUpgradeTestCase { int expectedCount = 10; - assertCount("test_index", expectedCount); + assertCount(indexName, expectedCount); if (isUpgradedCluster() && clusterSupportsDenseVectorTypeUpdate()) { Request updateMapping = new Request("PUT", "/" + indexName + "/_mapping"); @@ -118,9 +122,13 @@ public class DenseVectorMappingUpdateIT extends AbstractRollingUpgradeTestCase { .startObject("properties") .startObject("embedding") .field("type", "dense_vector") + .field("index", "true") .field("dims", 4) + .field("similarity", "cosine") .startObject("index_options") .field("type", "int8_hnsw") + .field("m", "16") + .field("ef_construction", "100") .endObject() .endObject() .endObject() @@ -132,7 +140,7 @@ public class DenseVectorMappingUpdateIT extends AbstractRollingUpgradeTestCase { index.setJsonEntity(BULK2); assertOK(client().performRequest(index)); expectedCount = 20; - assertCount("test_index", expectedCount); + assertCount(indexName, expectedCount); } } } @@ -152,7 +160,7 @@ public class DenseVectorMappingUpdateIT extends AbstractRollingUpgradeTestCase { Map response = entityAsMap(client().performRequest(new Request("GET", "_nodes"))); Map nodes = (Map) response.get("nodes"); - Predicate> nodeSupportsBulkApi = n -> Version.fromString(n.get("version").toString()).onOrAfter(Version.V_8_14_0); + Predicate> nodeSupportsBulkApi = n -> Version.fromString(n.get("version").toString()).onOrAfter(Version.V_8_15_0); return nodes.values().stream().map(o -> (Map) o).allMatch(nodeSupportsBulkApi); } diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java index ba873ef6bbd7..ae75069fa564 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java @@ -106,8 +106,9 @@ public class UpgradeWithOldIndexSettingsIT extends AbstractRollingUpgradeTestCas public void testMapperDynamicIndexSetting() throws IOException { assumeTrue( - "Setting deprecated in 6.x, but remained in 7.x and is no longer defined in 8.x", - getOldClusterTestVersion().before("8.0.0") + "Setting deprecated in 6.x, but was disallowed/removed incorrectly in some 7.x versions and can only be set safely in 7.17.22. " + + "Setting can't be used in 8.x ", + getOldClusterTestVersion().before("8.0.0") && getOldClusterTestVersion().after("7.17.21") ); String indexName = "my-index"; if (isOldCluster()) { diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.retrievers/10_standard_retriever.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.retrievers/10_standard_retriever.yml index fcd5b49c984c..99d723664097 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.retrievers/10_standard_retriever.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.retrievers/10_standard_retriever.yml @@ -473,6 +473,11 @@ setup: --- "standard retriever collapse": + - skip: + reason: "https://github.com/elastic/elasticsearch/issues/109476" + known_issues: + - cluster_feature: "gte_v8.13.0" + fixed_by: "gte_v8.14.0" - do: search: index: animals diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/170_knn_search_hex_encoded_byte_vectors.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/170_knn_search_hex_encoded_byte_vectors.yml index be1e619d046a..c4d8b1f0929b 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/170_knn_search_hex_encoded_byte_vectors.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/170_knn_search_hex_encoded_byte_vectors.yml @@ -164,8 +164,8 @@ setup: --- "Dynamic dimensions for hex-encoded string": - requires: - cluster_features: "gte_v8.15.0" - reason: 'hex encoding for byte vectors fixed in 8.15' + cluster_features: "gte_v8.14.1" + reason: 'hex encoding for byte vectors fixed in 8.14.1' - do: indices.create: diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/110_field_collapsing.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/110_field_collapsing.yml index c10d3c48259f..2eb8b729d2c6 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/110_field_collapsing.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/110_field_collapsing.yml @@ -1,4 +1,9 @@ setup: + - skip: + reason: "https://github.com/elastic/elasticsearch/issues/109476" + known_issues: + - cluster_feature: "gte_v8.13.0" + fixed_by: "gte_v8.14.0" - do: indices.create: index: test @@ -85,7 +90,6 @@ setup: --- "field collapsing and from": - - do: search: rest_total_hits_as_int: true diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/111_field_collapsing_with_max_score.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/111_field_collapsing_with_max_score.yml index 3c0364bb7834..b05916aa96e4 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/111_field_collapsing_with_max_score.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/111_field_collapsing_with_max_score.yml @@ -1,4 +1,9 @@ setup: + - skip: + reason: "https://github.com/elastic/elasticsearch/issues/109476" + known_issues: + - cluster_feature: "gte_v8.13.0" + fixed_by: "gte_v8.14.0" - requires: cluster_features: ["gte_v8.10.0"] reason: Collapse with max score was fixed in 8.10.0 diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/112_field_collapsing_with_rescore.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/112_field_collapsing_with_rescore.yml index 67819881f1b5..08a2c9c89e33 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/112_field_collapsing_with_rescore.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/112_field_collapsing_with_rescore.yml @@ -1,4 +1,9 @@ setup: + - skip: + reason: "https://github.com/elastic/elasticsearch/issues/109476" + known_issues: + - cluster_feature: "gte_v8.13.0" + fixed_by: "gte_v8.14.0" - requires: cluster_features: "gte_v8.15.0" reason: Collapse with rescore added in 8.15.0 diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/115_multiple_field_collapsing.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/115_multiple_field_collapsing.yml index 5bc3f8cde65e..69fd8f61261c 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/115_multiple_field_collapsing.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/115_multiple_field_collapsing.yml @@ -1,3 +1,9 @@ +setup: + - skip: + reason: "https://github.com/elastic/elasticsearch/issues/109476" + known_issues: + - cluster_feature: "gte_v8.13.0" + fixed_by: "gte_v8.14.0" --- "two levels fields collapsing": diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java index 61e5c1bfcc81..3712ad8c35f6 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java @@ -13,7 +13,8 @@ import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortedSetSelector; import org.apache.lucene.search.SortedSetSortField; import org.apache.lucene.util.Constants; -import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; +import org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.action.admin.indices.segments.IndexShardSegments; @@ -396,7 +397,12 @@ public class ShrinkIndexIT extends ESIntegTestCase { refreshClusterInfo(); // kick off a retry and wait until it's done! - ClusterRerouteResponse clusterRerouteResponse = clusterAdmin().prepareReroute().setRetryFailed(true).get(); + final var clusterRerouteResponse = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).setRetryFailed(true) + ) + ); long expectedShardSize = clusterRerouteResponse.getState().routingTable().index("target").shard(0).shard(0).getExpectedShardSize(); // we support the expected shard size in the allocator to sum up over the source index shards assertTrue("expected shard size must be set but wasn't: " + expectedShardSize, expectedShardSize > 0); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/SimpleDataNodesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/SimpleDataNodesIT.java index 770ca21fd689..8a239f7293e2 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/SimpleDataNodesIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/SimpleDataNodesIT.java @@ -11,6 +11,7 @@ package org.elasticsearch.cluster; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.UnavailableShardsException; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.ActiveShardCount; @@ -106,7 +107,7 @@ public class SimpleDataNodesIT extends ESIntegTestCase { internalCluster().startNode(); internalCluster().startNode(); - clusterAdmin().prepareReroute().setRetryFailed(true).get(); + ClusterRerouteUtils.rerouteRetryFailed(client()); } } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/AwarenessAllocationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/AwarenessAllocationIT.java index e6ea4823e86f..71418cb83deb 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/AwarenessAllocationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/AwarenessAllocationIT.java @@ -11,6 +11,7 @@ package org.elasticsearch.cluster.allocation; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetadata.State; import org.elasticsearch.cluster.routing.IndexRoutingTable; @@ -184,7 +185,7 @@ public class AwarenessAllocationIT extends ESIntegTestCase { .setWaitForNodes("3") .get(); assertThat(health.isTimedOut(), equalTo(false)); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); health = clusterAdmin().prepareHealth() .setIndices("test") .setWaitForEvents(Priority.LANGUID) @@ -210,7 +211,7 @@ public class AwarenessAllocationIT extends ESIntegTestCase { .setWaitForNodes("4") .get(); assertThat(health.isTimedOut(), equalTo(false)); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); health = clusterAdmin().prepareHealth() .setIndices("test") .setWaitForEvents(Priority.LANGUID) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/ClusterRerouteIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/ClusterRerouteIT.java index bacff31b480e..7c13171ea76a 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/ClusterRerouteIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/ClusterRerouteIT.java @@ -11,7 +11,9 @@ package org.elasticsearch.cluster.allocation; import org.apache.logging.log4j.Level; import org.apache.lucene.tests.util.LuceneTestCase; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction; import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; @@ -99,12 +101,14 @@ public class ClusterRerouteIT extends ESIntegTestCase { assertThat(state.getRoutingNodes().unassigned().size(), equalTo(2)); logger.info("--> explicitly allocate shard 1, *under dry_run*"); - state = clusterAdmin().prepareReroute() - .setExplain(randomBoolean()) - .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) - .setDryRun(true) - .get() - .getState(); + state = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).explain(randomBoolean()) + .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) + .dryRun(true) + ) + ).getState(); assertThat(state.getRoutingNodes().unassigned().size(), equalTo(1)); assertThat( state.getRoutingNodes().node(state.nodes().resolveNode(node_1).getId()).iterator().next().state(), @@ -116,11 +120,13 @@ public class ClusterRerouteIT extends ESIntegTestCase { assertThat(state.getRoutingNodes().unassigned().size(), equalTo(2)); logger.info("--> explicitly allocate shard 1, actually allocating, no dry run"); - state = clusterAdmin().prepareReroute() - .setExplain(randomBoolean()) - .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) - .get() - .getState(); + state = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).explain(randomBoolean()) + .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) + ) + ).getState(); assertThat(state.getRoutingNodes().unassigned().size(), equalTo(1)); assertThat( state.getRoutingNodes().node(state.nodes().resolveNode(node_1).getId()).iterator().next().state(), @@ -143,11 +149,13 @@ public class ClusterRerouteIT extends ESIntegTestCase { ); logger.info("--> move shard 1 primary from node1 to node2"); - state = clusterAdmin().prepareReroute() - .setExplain(randomBoolean()) - .add(new MoveAllocationCommand("test", 0, node_1, node_2)) - .get() - .getState(); + state = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).explain(randomBoolean()) + .add(new MoveAllocationCommand("test", 0, node_1, node_2)) + ) + ).getState(); assertThat( state.getRoutingNodes().node(state.nodes().resolveNode(node_1).getId()).iterator().next().state(), @@ -250,11 +258,13 @@ public class ClusterRerouteIT extends ESIntegTestCase { assertThat(state.getRoutingNodes().unassigned().size(), equalTo(2)); logger.info("--> explicitly allocate shard 1, actually allocating, no dry run"); - state = clusterAdmin().prepareReroute() - .setExplain(randomBoolean()) - .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) - .get() - .getState(); + state = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).explain(randomBoolean()) + .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) + ) + ).getState(); assertThat(state.getRoutingNodes().unassigned().size(), equalTo(1)); assertThat( state.getRoutingNodes().node(state.nodes().resolveNode(node_1).getId()).iterator().next().state(), @@ -295,17 +305,19 @@ public class ClusterRerouteIT extends ESIntegTestCase { internalCluster().startNode(commonSettings); // wait a bit for the cluster to realize that the shard is not there... // TODO can we get around this? the cluster is RED, so what do we wait for? - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); assertThat( clusterAdmin().prepareHealth().setIndices("test").setWaitForNodes("2").get().getStatus(), equalTo(ClusterHealthStatus.RED) ); logger.info("--> explicitly allocate primary"); - state = clusterAdmin().prepareReroute() - .setExplain(randomBoolean()) - .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) - .get() - .getState(); + state = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).explain(randomBoolean()) + .add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node_1, true)) + ) + ).getState(); assertThat(state.getRoutingNodes().unassigned().size(), equalTo(1)); assertThat( state.getRoutingNodes().node(state.nodes().resolveNode(node_1).getId()).iterator().next().state(), @@ -350,7 +362,12 @@ public class ClusterRerouteIT extends ESIntegTestCase { logger.info("--> try to move the shard from node1 to node2"); MoveAllocationCommand cmd = new MoveAllocationCommand("test", 0, node_1, node_2); - ClusterRerouteResponse resp = clusterAdmin().prepareReroute().add(cmd).setExplain(true).get(); + ClusterRerouteResponse resp = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).add(cmd).explain(true) + ) + ); RoutingExplanations e = resp.getExplanations(); assertThat(e.explanations().size(), equalTo(1)); RerouteExplanation explanation = e.explanations().get(0); @@ -398,11 +415,14 @@ public class ClusterRerouteIT extends ESIntegTestCase { ); AllocationCommand dryRunAllocation = new AllocateEmptyPrimaryAllocationCommand(indexName, 0, nodeName1, true); - ClusterRerouteResponse dryRunResponse = clusterAdmin().prepareReroute() - .setExplain(randomBoolean()) - .setDryRun(true) - .add(dryRunAllocation) - .get(); + ClusterRerouteResponse dryRunResponse = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).explain(randomBoolean()) + .dryRun(true) + .add(dryRunAllocation) + ) + ); // during a dry run, messages exist but are not logged or exposed assertThat(dryRunResponse.getExplanations().getYesDecisionMessages(), hasSize(1)); @@ -431,11 +451,16 @@ public class ClusterRerouteIT extends ESIntegTestCase { AllocationCommand yesDecisionAllocation = new AllocateEmptyPrimaryAllocationCommand(indexName, 0, nodeName1, true); AllocationCommand noDecisionAllocation = new AllocateEmptyPrimaryAllocationCommand("noexist", 1, nodeName2, true); - ClusterRerouteResponse response = clusterAdmin().prepareReroute() - .setExplain(true) // so we get a NO decision back rather than an exception - .add(yesDecisionAllocation) - .add(noDecisionAllocation) - .get(); + ClusterRerouteResponse response = safeGet( + client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT) + // set explain(true) so we get a NO decision back rather than an exception + .explain(true) + .add(yesDecisionAllocation) + .add(noDecisionAllocation) + ) + ); assertThat(response.getExplanations().getYesDecisionMessages(), hasSize(1)); assertThat(response.getExplanations().getYesDecisionMessages().get(0), containsString("allocated an empty primary")); @@ -482,9 +507,9 @@ public class ClusterRerouteIT extends ESIntegTestCase { )) { try { enableIndexBlock("test-blocks", blockSetting); - assertAcked( - clusterAdmin().prepareReroute() - .add(new MoveAllocationCommand("test-blocks", 0, nodesIds.get(toggle % 2), nodesIds.get(++toggle % 2))) + ClusterRerouteUtils.reroute( + client(), + new MoveAllocationCommand("test-blocks", 0, nodesIds.get(toggle % 2), nodesIds.get(++toggle % 2)) ); ClusterHealthResponse healthResponse = clusterAdmin().prepareHealth() @@ -502,8 +527,11 @@ public class ClusterRerouteIT extends ESIntegTestCase { try { setClusterReadOnly(true); assertBlocked( - clusterAdmin().prepareReroute() - .add(new MoveAllocationCommand("test-blocks", 1, nodesIds.get(toggle % 2), nodesIds.get(++toggle % 2))) + null, + ClusterRerouteUtils.expectRerouteFailure( + client(), + new MoveAllocationCommand("test-blocks", 1, nodesIds.get(toggle % 2), nodesIds.get(++toggle % 2)) + ) ); } finally { setClusterReadOnly(false); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/FilteringAllocationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/FilteringAllocationIT.java index ae79c388aa10..5f54b32ab4a1 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/FilteringAllocationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/allocation/FilteringAllocationIT.java @@ -8,6 +8,7 @@ package org.elasticsearch.cluster.allocation; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.cluster.metadata.AutoExpandReplicas; @@ -160,7 +161,7 @@ public class FilteringAllocationIT extends ESIntegTestCase { } logger.info("--> remove index from the first node"); updateIndexSettings(Settings.builder().put("index.routing.allocation.exclude._name", node_0), "test"); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); ensureGreen("test"); logger.info("--> verify all shards are allocated on node_1 now"); @@ -175,7 +176,7 @@ public class FilteringAllocationIT extends ESIntegTestCase { logger.info("--> disable allocation filtering "); updateIndexSettings(Settings.builder().put("index.routing.allocation.exclude._name", ""), "test"); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); ensureGreen("test"); logger.info("--> verify that there are shards allocated on both nodes now"); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java index a25de555ce26..8cee57ee34b8 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/AllocationIdIT.java @@ -10,6 +10,7 @@ package org.elasticsearch.cluster.routing; import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplanationUtils; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.stats.ShardStats; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.cluster.ClusterState; @@ -106,7 +107,7 @@ public class AllocationIdIT extends ESIntegTestCase { checkNoValidShardCopy(indexName, shardId); // allocate stale primary - client(node1).admin().cluster().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(indexName, 0, node1, true)).get(); + ClusterRerouteUtils.reroute(client(node1), new AllocateStalePrimaryAllocationCommand(indexName, 0, node1, true)); // allocation fails due to corruption marker assertBusy(() -> { @@ -127,7 +128,7 @@ public class AllocationIdIT extends ESIntegTestCase { checkNoValidShardCopy(indexName, shardId); // no any valid shard is there; have to invoke AllocateStalePrimary again - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(indexName, 0, node1, true)).get(); + ClusterRerouteUtils.reroute(client(), new AllocateStalePrimaryAllocationCommand(indexName, 0, node1, true)); ensureYellow(indexName); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/PrimaryAllocationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/PrimaryAllocationIT.java index 72594fef8c6e..d97063454920 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/PrimaryAllocationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/PrimaryAllocationIT.java @@ -9,7 +9,9 @@ package org.elasticsearch.cluster.routing; import org.elasticsearch.action.DocWriteResponse; -import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequestBuilder; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; +import org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction; import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresRequest; import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresResponse; import org.elasticsearch.action.admin.indices.shards.TransportIndicesShardStoresAction; @@ -156,12 +158,13 @@ public class PrimaryAllocationIT extends ESIntegTestCase { logger.info("--> check that old primary shard does not get promoted to primary again"); // kick reroute and wait for all shard states to be fetched - client(master).admin().cluster().prepareReroute().get(); + ClusterRerouteUtils.reroute(client(master)); assertBusy( () -> assertThat(internalCluster().getInstance(GatewayAllocator.class, master).getNumberOfInFlightFetches(), equalTo(0)) ); // kick reroute a second time and check that all shards are unassigned - assertThat(client(master).admin().cluster().prepareReroute().get().getState().getRoutingNodes().unassigned().size(), equalTo(2)); + ClusterRerouteUtils.reroute(client(master)); + assertThat(client(master).admin().cluster().prepareState().get().getState().getRoutingNodes().unassigned().size(), equalTo(2)); return inSyncDataPathSettings; } @@ -207,11 +210,16 @@ public class PrimaryAllocationIT extends ESIntegTestCase { ); logger.info("--> force allocation of stale copy to node that does not have shard copy"); - Throwable iae = expectThrows( - IllegalArgumentException.class, - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand("test", 0, dataNodeWithNoShardCopy, true)) + assertEquals( + "No data for shard [0] of index [test] found on any node", + asInstanceOf( + IllegalArgumentException.class, + ClusterRerouteUtils.expectRerouteFailure( + client(), + new AllocateStalePrimaryAllocationCommand("test", 0, dataNodeWithNoShardCopy, true) + ) + ).getMessage() ); - assertThat(iae.getMessage(), equalTo("No data for shard [0] of index [test] found on any node")); logger.info("--> wait until shard is failed and becomes unassigned again"); assertTrue( @@ -252,16 +260,16 @@ public class PrimaryAllocationIT extends ESIntegTestCase { TransportIndicesShardStoresAction.TYPE, new IndicesShardStoresRequest(idxName) ).get().getStoreStatuses().get(idxName); - ClusterRerouteRequestBuilder rerouteBuilder = clusterAdmin().prepareReroute(); + final var rerouteRequest = new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT); for (Map.Entry> shardStoreStatuses : storeStatuses.entrySet()) { int shardId = shardStoreStatuses.getKey(); IndicesShardStoresResponse.StoreStatus storeStatus = randomFrom(shardStoreStatuses.getValue()); logger.info("--> adding allocation command for shard {}", shardId); // force allocation based on node id if (useStaleReplica) { - rerouteBuilder.add(new AllocateStalePrimaryAllocationCommand(idxName, shardId, storeStatus.getNode().getId(), true)); + rerouteRequest.add(new AllocateStalePrimaryAllocationCommand(idxName, shardId, storeStatus.getNode().getId(), true)); } else { - rerouteBuilder.add(new AllocateEmptyPrimaryAllocationCommand(idxName, shardId, storeStatus.getNode().getId(), true)); + rerouteRequest.add(new AllocateEmptyPrimaryAllocationCommand(idxName, shardId, storeStatus.getNode().getId(), true)); } } @@ -280,7 +288,7 @@ public class PrimaryAllocationIT extends ESIntegTestCase { final ClusterService clusterService = internalCluster().getInstance(ClusterService.class, master); clusterService.addListener(clusterStateListener); - rerouteBuilder.get(); + assertAcked(safeGet(client().execute(TransportClusterRerouteAction.TYPE, rerouteRequest))); assertTrue(clusterStateChangeLatch.await(30, TimeUnit.SECONDS)); clusterService.removeListener(clusterStateListener); @@ -341,13 +349,16 @@ public class PrimaryAllocationIT extends ESIntegTestCase { .forEach(status -> nodeNames.remove(status.getNode().getName())); assertThat(nodeNames, hasSize(1)); final String nodeWithoutData = nodeNames.get(0); - Throwable iae = expectThrows( - IllegalArgumentException.class, - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(idxName, shardId, nodeWithoutData, true)) - ); - assertThat( - iae.getMessage(), - equalTo("No data for shard [" + shardId + "] of index [" + idxName + "] found on node [" + nodeWithoutData + ']') + + assertEquals( + "No data for shard [" + shardId + "] of index [" + idxName + "] found on node [" + nodeWithoutData + ']', + asInstanceOf( + IllegalArgumentException.class, + ClusterRerouteUtils.expectRerouteFailure( + client(), + new AllocateStalePrimaryAllocationCommand(idxName, shardId, nodeWithoutData, true) + ) + ).getMessage() ); } @@ -359,22 +370,29 @@ public class PrimaryAllocationIT extends ESIntegTestCase { ensureGreen(); final String nodeWithoutData = randomFrom(dataNodes); final int shardId = 0; - IllegalArgumentException iae = expectThrows( - IllegalArgumentException.class, - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(idxName, shardId, nodeWithoutData, true)) + assertEquals( + "[allocate_stale_primary] primary [" + idxName + "][" + shardId + "] is already assigned", + asInstanceOf( + IllegalArgumentException.class, + ClusterRerouteUtils.expectRerouteFailure( + client(), + new AllocateStalePrimaryAllocationCommand(idxName, shardId, nodeWithoutData, true) + ) + ).getMessage() ); - assertThat(iae.getMessage(), equalTo("[allocate_stale_primary] primary [" + idxName + "][" + shardId + "] is already assigned")); } public void testForceStaleReplicaToBePromotedForMissingIndex() { internalCluster().startMasterOnlyNode(Settings.EMPTY); final String dataNode = internalCluster().startDataOnlyNode(); final String idxName = "test"; - IndexNotFoundException ex = expectThrows( - IndexNotFoundException.class, - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(idxName, 0, dataNode, true)) + assertEquals( + idxName, + asInstanceOf( + IndexNotFoundException.class, + ClusterRerouteUtils.expectRerouteFailure(client(), new AllocateStalePrimaryAllocationCommand(idxName, 0, dataNode, true)) + ).getIndex().getName() ); - assertThat(ex.getIndex().getName(), equalTo(idxName)); } public void testForcePrimaryShardIfAllocationDecidersSayNoAfterIndexCreation() throws ExecutionException, InterruptedException { @@ -386,7 +404,7 @@ public class PrimaryAllocationIT extends ESIntegTestCase { assertThat(clusterAdmin().prepareState().get().getState().getRoutingTable().shardRoutingTable("test", 0).assignedShards(), empty()); - clusterAdmin().prepareReroute().add(new AllocateEmptyPrimaryAllocationCommand("test", 0, node, true)).get(); + ClusterRerouteUtils.reroute(client(), new AllocateEmptyPrimaryAllocationCommand("test", 0, node, true)); ensureGreen("test"); } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/ShardRoutingRoleIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/ShardRoutingRoleIT.java index 76311387115d..bb9324dd7d10 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/ShardRoutingRoleIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/ShardRoutingRoleIT.java @@ -11,6 +11,7 @@ package org.elasticsearch.cluster.routing; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsGroup; import org.elasticsearch.action.admin.indices.refresh.TransportUnpromotableShardRefreshAction; import org.elasticsearch.action.search.ClosePointInTimeRequest; @@ -422,7 +423,7 @@ public class ShardRoutingRoleIT extends ESIntegTestCase { updateIndexSettings(Settings.builder().put(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_PREFIX + "._name", "not-a-node"), "test"); AllocationCommand cancelPrimaryCommand; while ((cancelPrimaryCommand = getCancelPrimaryCommand()) != null) { - clusterAdmin().prepareReroute().add(cancelPrimaryCommand).get(); + ClusterRerouteUtils.reroute(client(), cancelPrimaryCommand); } } finally { masterClusterService.removeListener(routingTableWatcher); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java index 8499bc8aef4a..16be816b69bc 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java @@ -8,6 +8,7 @@ package org.elasticsearch.cluster.routing.allocation.decider; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.admin.indices.stats.ShardStats; @@ -314,7 +315,7 @@ public class DiskThresholdDeciderIT extends DiskUsageIntegTestCase { .values() .stream() .allMatch(e -> e.freeBytes() > WATERMARK_BYTES)) { - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); } assertFalse( diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/UpdateShardAllocationSettingsIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/UpdateShardAllocationSettingsIT.java index da1156953e26..921ed3265f1b 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/UpdateShardAllocationSettingsIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/routing/allocation/decider/UpdateShardAllocationSettingsIT.java @@ -7,6 +7,7 @@ */ package org.elasticsearch.cluster.routing.allocation.decider; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.routing.ShardRoutingState; import org.elasticsearch.common.settings.Settings; @@ -50,7 +51,7 @@ public class UpdateShardAllocationSettingsIT extends ESIntegTestCase { .put(EnableAllocationDecider.INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE), "test" ); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); ensureGreen(); assertAllShardsOnNodes("test", firstNode); assertAllShardsOnNodes("test_1", firstNode); @@ -65,7 +66,7 @@ public class UpdateShardAllocationSettingsIT extends ESIntegTestCase { "test" ); logger.info("--> balance index [test]"); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); ensureGreen("test"); Set test = assertAllShardsOnNodes("test", firstNode, secondNode); assertThat("index: [test] expected to be rebalanced on both nodes", test.size(), equalTo(2)); @@ -80,7 +81,7 @@ public class UpdateShardAllocationSettingsIT extends ESIntegTestCase { ) ); logger.info("--> balance index [test_1]"); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); ensureGreen("test_1"); Set test_1 = assertAllShardsOnNodes("test_1", firstNode, secondNode); assertThat("index: [test_1] expected to be rebalanced on both nodes", test_1.size(), equalTo(2)); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/discovery/ClusterDisruptionIT.java b/server/src/internalClusterTest/java/org/elasticsearch/discovery/ClusterDisruptionIT.java index cd9adea500db..a0fa63aa58ab 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/discovery/ClusterDisruptionIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/discovery/ClusterDisruptionIT.java @@ -13,6 +13,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.NoShardAvailableActionException; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.support.PlainActionFuture; @@ -233,7 +234,7 @@ public class ClusterDisruptionIT extends AbstractDisruptionTestCase { // is the super-connected node and recovery source and target are on opposite sides of the bridge if (disruptionScheme instanceof NetworkDisruption networkDisruption && networkDisruption.getDisruptedLinks() instanceof Bridge) { - assertBusy(() -> assertAcked(clusterAdmin().prepareReroute().setRetryFailed(true))); + assertBusy(() -> ClusterRerouteUtils.rerouteRetryFailed(client())); } ensureGreen("test"); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/discovery/MasterDisruptionIT.java b/server/src/internalClusterTest/java/org/elasticsearch/discovery/MasterDisruptionIT.java index af254d42ec3e..3e7e4d47e7a2 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/discovery/MasterDisruptionIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/discovery/MasterDisruptionIT.java @@ -8,6 +8,7 @@ package org.elasticsearch.discovery; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.admin.indices.stats.ShardStats; import org.elasticsearch.action.bulk.BulkRequestBuilder; @@ -116,7 +117,7 @@ public class MasterDisruptionIT extends AbstractDisruptionTestCase { logger.info("issue a reroute"); // trigger a reroute now, instead of waiting for the background reroute of RerouteService - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); // and wait for it to finish and for the cluster to stabilize ensureGreen("test"); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java index ef4616fdd0b4..bdfe629f4bab 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java @@ -20,6 +20,7 @@ import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.NativeFSLockFactory; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.flush.FlushRequest; import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse; import org.elasticsearch.action.admin.indices.stats.ShardStats; @@ -219,7 +220,7 @@ public class RemoveCorruptedShardDataCommandIT extends ESIntegTestCase { ); }); - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(indexName, 0, nodeId, true)).get(); + ClusterRerouteUtils.reroute(client(), new AllocateStalePrimaryAllocationCommand(indexName, 0, nodeId, true)); assertBusy(() -> { final var explanation = getClusterAllocationExplanation(client(), indexName, 0, true); @@ -373,7 +374,7 @@ public class RemoveCorruptedShardDataCommandIT extends ESIntegTestCase { ); }); - clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand(indexName, 0, primaryNodeId, true)).get(); + ClusterRerouteUtils.reroute(client(), new AllocateStalePrimaryAllocationCommand(indexName, 0, primaryNodeId, true)); assertBusy(() -> { final var explanation = getClusterAllocationExplanation(client(), indexName, 0, true); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedFileIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedFileIT.java index 7e3df8d8e1cb..2fed0a45032a 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedFileIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedFileIT.java @@ -19,6 +19,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresRequest; @@ -284,7 +285,7 @@ public class CorruptedFileIT extends ESIntegTestCase { * we corrupted the primary shard - now lets make sure we never recover from it successfully */ setReplicaCount(1, "test"); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); boolean didClusterTurnRed = waitUntil(() -> { ClusterHealthStatus test = clusterAdmin().health(new ClusterHealthRequest("test")).actionGet().getStatus(); @@ -368,7 +369,7 @@ public class CorruptedFileIT extends ESIntegTestCase { .put("index.routing.allocation.include._name", primariesNode.getName() + "," + unluckyNode.getName()), "test" ); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); hasCorrupted.await(); corrupt.set(false); ensureGreen(); @@ -493,7 +494,7 @@ public class CorruptedFileIT extends ESIntegTestCase { .put("index.routing.allocation.exclude._name", unluckyNode.getName()), "test" ); - clusterAdmin().prepareReroute().setRetryFailed(true).get(); + ClusterRerouteUtils.rerouteRetryFailed(client()); ensureGreen("test"); assertThatAllShards("test", shard -> { assertThat(shard.primaryShard().currentNodeId(), not(equalTo(unluckyNode.getId()))); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indexlifecycle/IndexLifecycleActionIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indexlifecycle/IndexLifecycleActionIT.java index 28a5ad9c2912..5c4cdc8cde85 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indexlifecycle/IndexLifecycleActionIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indexlifecycle/IndexLifecycleActionIT.java @@ -10,6 +10,7 @@ package org.elasticsearch.indexlifecycle; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; @@ -79,7 +80,7 @@ public class IndexLifecycleActionIT extends ESIntegTestCase { final String node2 = getLocalNodeId(server_2); // explicitly call reroute, so shards will get relocated to the new node (we delay it in ES in case other nodes join) - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); clusterHealth = clusterAdmin().health( new ClusterHealthRequest(new String[] {}).waitForGreenStatus().waitForNodes("2").waitForNoRelocatingShards(true) @@ -120,7 +121,7 @@ public class IndexLifecycleActionIT extends ESIntegTestCase { final String node3 = getLocalNodeId(server_3); // explicitly call reroute, so shards will get relocated to the new node (we delay it in ES in case other nodes join) - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); clusterHealth = clusterAdmin().prepareHealth() .setWaitForGreenStatus() @@ -174,7 +175,7 @@ public class IndexLifecycleActionIT extends ESIntegTestCase { assertThat(clusterHealth.isTimedOut(), equalTo(false)); assertThat(clusterHealth.getStatus(), equalTo(ClusterHealthStatus.GREEN)); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); clusterHealth = clusterAdmin().prepareHealth() .setWaitForGreenStatus() diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/IndicesLifecycleListenerIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/IndicesLifecycleListenerIT.java index d5cbb215781b..b224d70eed8f 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/IndicesLifecycleListenerIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/IndicesLifecycleListenerIT.java @@ -8,6 +8,7 @@ package org.elasticsearch.indices; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.cluster.routing.ShardRoutingState; import org.elasticsearch.cluster.routing.allocation.command.MoveAllocationCommand; @@ -115,7 +116,7 @@ public class IndicesLifecycleListenerIT extends ESIntegTestCase { throw new RuntimeException("FAIL"); } }); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand("index1", 0, node1, node2)).get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("index1", 0, node1, node2)); ensureGreen("index1"); var state = clusterAdmin().prepareState().get().getState(); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/cluster/ShardLockFailureIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/cluster/ShardLockFailureIT.java index 874ba7b42690..28e89f459055 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/cluster/ShardLockFailureIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/cluster/ShardLockFailureIT.java @@ -11,6 +11,7 @@ package org.elasticsearch.indices.cluster; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.LogEvent; import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider; @@ -28,8 +29,6 @@ import org.elasticsearch.test.junit.annotations.TestLogging; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; - public class ShardLockFailureIT extends ESIntegTestCase { @TestLogging(reason = "checking DEBUG logs from ICSS", value = "org.elasticsearch.indices.cluster.IndicesClusterStateService:DEBUG") @@ -165,7 +164,7 @@ public class ShardLockFailureIT extends ESIntegTestCase { assertEquals(1, clusterHealthResponse.getUnassignedShards()); } - assertAcked(clusterAdmin().prepareReroute().setRetryFailed(true)); + ClusterRerouteUtils.rerouteRetryFailed(client()); ensureGreen(indexName); } } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexPrimaryRelocationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexPrimaryRelocationIT.java index 779072272e59..a9e06fe438c4 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexPrimaryRelocationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexPrimaryRelocationIT.java @@ -11,6 +11,7 @@ package org.elasticsearch.indices.recovery; import org.apache.logging.log4j.Level; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNode; @@ -63,9 +64,7 @@ public class IndexPrimaryRelocationIT extends ESIntegTestCase { relocationTarget = randomFrom(dataNodes); } logger.info("--> [iteration {}] relocating from {} to {} ", i, relocationSource.getName(), relocationTarget.getName()); - clusterAdmin().prepareReroute() - .add(new MoveAllocationCommand("test", 0, relocationSource.getId(), relocationTarget.getId())) - .get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("test", 0, relocationSource.getId(), relocationTarget.getId())); ClusterHealthResponse clusterHealthResponse = clusterAdmin().prepareHealth() .setTimeout(TimeValue.timeValueSeconds(60)) .setWaitForEvents(Priority.LANGUID) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java index 23963fe50aa4..14b13addac84 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java @@ -28,6 +28,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.admin.indices.recovery.RecoveryRequest; @@ -281,7 +282,7 @@ public class IndexRecoveryIT extends AbstractIndexRecoveryIntegTestCase { */ public void startShardRecovery(String sourceNode, String targetNode) throws Exception { logger.info("--> updating cluster settings with moving shard from node `{}` to node `{}`", sourceNode, targetNode); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand(INDEX_NAME, 0, sourceNode, targetNode)).get().getState(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand(INDEX_NAME, 0, sourceNode, targetNode)); logger.info("--> requesting shard recovery"); indicesAdmin().prepareRecoveries(INDEX_NAME).get(); @@ -553,7 +554,7 @@ public class IndexRecoveryIT extends AbstractIndexRecoveryIntegTestCase { throttleRecovery10Seconds(shardSize); logger.info("--> move shard from: {} to: {}", nodeA, nodeB); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand(INDEX_NAME, 0, nodeA, nodeB)).get().getState(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand(INDEX_NAME, 0, nodeA, nodeB)); logger.info("--> waiting for recovery to start both on source and target"); final Index index = resolveIndex(INDEX_NAME); @@ -639,7 +640,7 @@ public class IndexRecoveryIT extends AbstractIndexRecoveryIntegTestCase { throttleRecovery10Seconds(shardSize); logger.info("--> move replica shard from: {} to: {}", nodeA, nodeC); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand(INDEX_NAME, 0, nodeA, nodeC)).get().getState(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand(INDEX_NAME, 0, nodeA, nodeC)); response = indicesAdmin().prepareRecoveries(INDEX_NAME).get(); recoveryStates = response.shardRecoveryStates().get(INDEX_NAME); @@ -1643,7 +1644,7 @@ public class IndexRecoveryIT extends AbstractIndexRecoveryIntegTestCase { internalCluster().stopRandomDataNode(); internalCluster().stopRandomDataNode(); final String nodeWithoutData = internalCluster().startDataOnlyNode(); - assertAcked(clusterAdmin().prepareReroute().add(new AllocateEmptyPrimaryAllocationCommand(indexName, 0, nodeWithoutData, true))); + ClusterRerouteUtils.reroute(client(), new AllocateEmptyPrimaryAllocationCommand(indexName, 0, nodeWithoutData, true)); internalCluster().startDataOnlyNode(randomNodeDataPathSettings); ensureGreen(); for (ShardStats shardStats : indicesAdmin().prepareStats(indexName).get().getIndex(indexName).getShards()) { @@ -1712,7 +1713,7 @@ public class IndexRecoveryIT extends AbstractIndexRecoveryIntegTestCase { ); internalCluster().startNode(); internalCluster().startNode(); - clusterAdmin().prepareReroute().setRetryFailed(true).get(); + ClusterRerouteUtils.rerouteRetryFailed(client()); assertAcked(indicesAdmin().prepareDelete("test")); // cancel recoveries assertBusy(() -> { for (PeerRecoverySourceService recoveryService : internalCluster().getDataNodeInstances(PeerRecoverySourceService.class)) { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/state/CloseWhileRelocatingShardsIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/state/CloseWhileRelocatingShardsIT.java index b66a0b0f3be4..b160834d675d 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/state/CloseWhileRelocatingShardsIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/state/CloseWhileRelocatingShardsIT.java @@ -7,13 +7,13 @@ */ package org.elasticsearch.indices.state; -import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.routing.IndexRoutingTable; import org.elasticsearch.cluster.routing.ShardRouting; -import org.elasticsearch.cluster.routing.allocation.command.AllocationCommands; +import org.elasticsearch.cluster.routing.allocation.command.AllocationCommand; import org.elasticsearch.cluster.routing.allocation.command.MoveAllocationCommand; import org.elasticsearch.cluster.routing.allocation.decider.ConcurrentRebalanceAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider; @@ -125,7 +125,7 @@ public class CloseWhileRelocatingShardsIT extends ESIntegTestCase { final CountDownLatch release = new CountDownLatch(indices.length); // relocate one shard for every index to be closed - final AllocationCommands commands = new AllocationCommands(); + final var commands = new ArrayList(); for (final String index : indices) { final NumShards numShards = getNumShards(index); final int shardId = numShards.numPrimaries == 1 ? 0 : randomIntBetween(0, numShards.numPrimaries - 1); @@ -146,8 +146,7 @@ public class CloseWhileRelocatingShardsIT extends ESIntegTestCase { } // Build the list of shards for which recoveries will be blocked - final Set blockedShards = commands.commands() - .stream() + final Set blockedShards = commands.stream() .map(c -> (MoveAllocationCommand) c) .map(c -> new ShardId(clusterService.state().metadata().index(c.index()).getIndex(), c.shardId())) .collect(Collectors.toSet()); @@ -185,7 +184,7 @@ public class CloseWhileRelocatingShardsIT extends ESIntegTestCase { } } - assertAcked(clusterAdmin().reroute(new ClusterRerouteRequest().commands(commands)).get()); + ClusterRerouteUtils.reroute(client(), commands.toArray(AllocationCommand[]::new)); // start index closing threads final List threads = new ArrayList<>(); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java index 5805eab83123..5eeb07968ce4 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/store/IndicesStoreIntegrationIT.java @@ -11,6 +11,7 @@ package org.elasticsearch.indices.store; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.health.ClusterHealthStatus; @@ -128,7 +129,7 @@ public class IndicesStoreIntegrationIT extends ESIntegTestCase { logger.info("--> stopping disruption"); disruption.stopDisrupting(); } else { - internalCluster().client().admin().cluster().prepareReroute().add(new MoveAllocationCommand("test", 0, node_1, node_3)).get(); + ClusterRerouteUtils.reroute(internalCluster().client(), new MoveAllocationCommand("test", 0, node_1, node_3)); } clusterHealth = clusterAdmin().prepareHealth().setWaitForNoRelocatingShards(true).get(); assertThat(clusterHealth.isTimedOut(), equalTo(false)); @@ -172,7 +173,7 @@ public class IndicesStoreIntegrationIT extends ESIntegTestCase { } } }); - internalCluster().client().admin().cluster().prepareReroute().add(new MoveAllocationCommand(index, shard, nodeFrom, nodeTo)).get(); + ClusterRerouteUtils.reroute(internalCluster().client(), new MoveAllocationCommand(index, shard, nodeFrom, nodeTo)); logger.info("--> waiting for relocation to start"); beginRelocationLatch.await(); logger.info("--> starting disruption"); @@ -223,7 +224,7 @@ public class IndicesStoreIntegrationIT extends ESIntegTestCase { }); logger.info("--> move shard from {} to {}, and wait for relocation to finish", node_1, node_2); - internalCluster().client().admin().cluster().prepareReroute().add(new MoveAllocationCommand("test", 0, node_1, node_2)).get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("test", 0, node_1, node_2)); shardActiveRequestSent.await(); ClusterHealthResponse clusterHealth = clusterAdmin().prepareHealth().setWaitForNoRelocatingShards(true).get(); assertThat(clusterHealth.isTimedOut(), equalTo(false)); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/recovery/RelocationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/recovery/RelocationIT.java index 4c3c05992a44..17daf403e056 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/recovery/RelocationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/recovery/RelocationIT.java @@ -13,7 +13,10 @@ import org.apache.lucene.tests.util.English; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; +import org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction; import org.elasticsearch.action.admin.indices.stats.ShardStats; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.support.WriteRequest; @@ -144,7 +147,7 @@ public class RelocationIT extends ESIntegTestCase { assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); logger.info("--> relocate the shard from node1 to node2"); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand("test", 0, node_1, node_2)).get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("test", 0, node_1, node_2)); clusterHealthResponse = clusterAdmin().prepareHealth() .setWaitForEvents(Priority.LANGUID) @@ -207,7 +210,7 @@ public class RelocationIT extends ESIntegTestCase { logger.debug("--> Allow indexer to index [{}] documents", numDocs); indexer.continueIndexing(numDocs); logger.info("--> START relocate the shard from {} to {}", nodes[fromNode], nodes[toNode]); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand("test", 0, nodes[fromNode], nodes[toNode])).get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("test", 0, nodes[fromNode], nodes[toNode])); if (rarely()) { logger.debug("--> flushing"); indicesAdmin().prepareFlush().get(); @@ -334,7 +337,7 @@ public class RelocationIT extends ESIntegTestCase { logger.info("--> START relocate the shard from {} to {}", nodes[fromNode], nodes[toNode]); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand("test", 0, nodes[fromNode], nodes[toNode])).get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("test", 0, nodes[fromNode], nodes[toNode])); logger.debug("--> index [{}] documents", builders1.size()); indexRandom(false, true, builders1); @@ -555,7 +558,7 @@ public class RelocationIT extends ESIntegTestCase { assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); logger.info("--> relocate the shard from node1 to node2"); - clusterAdmin().prepareReroute().add(new MoveAllocationCommand("test", 0, node1, node2)).get(); + ClusterRerouteUtils.reroute(client(), new MoveAllocationCommand("test", 0, node1, node2)); clusterHealthResponse = clusterAdmin().prepareHealth() .setWaitForEvents(Priority.LANGUID) @@ -606,9 +609,10 @@ public class RelocationIT extends ESIntegTestCase { assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); logger.info("--> relocate the shard from node1 to node2"); - ActionFuture relocationListener = clusterAdmin().prepareReroute() - .add(new MoveAllocationCommand("test", 0, node1, node2)) - .execute(); + ActionFuture relocationListener = client().execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).add(new MoveAllocationCommand("test", 0, node1, node2)) + ); logger.info("--> index 100 docs while relocating"); for (int i = 20; i < 120; i++) { pendingIndexResponses.add( @@ -618,7 +622,7 @@ public class RelocationIT extends ESIntegTestCase { .execute() ); } - relocationListener.actionGet(); + safeGet(relocationListener); clusterHealthResponse = clusterAdmin().prepareHealth() .setWaitForEvents(Priority.LANGUID) .setWaitForNoRelocatingShards(true) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/basic/SearchWhileRelocatingIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/basic/SearchWhileRelocatingIT.java index 03a21210630b..657158327bf0 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/basic/SearchWhileRelocatingIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/basic/SearchWhileRelocatingIT.java @@ -10,6 +10,7 @@ package org.elasticsearch.search.basic; import org.elasticsearch.action.NoShardAvailableActionException; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.common.Priority; @@ -118,7 +119,7 @@ public class SearchWhileRelocatingIT extends ESIntegTestCase { threads[j].start(); } allowNodes("test", between(1, 3)); - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); stop.set(true); for (int j = 0; j < threads.length; j++) { threads[j].join(); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java index ae3347dafd55..9d3ce1c99b55 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java @@ -13,6 +13,7 @@ import org.apache.http.entity.StringEntity; import org.apache.logging.log4j.Level; import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.fieldcaps.FieldCapabilities; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesFailure; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; @@ -549,18 +550,14 @@ public class FieldCapabilitiesIT extends ESIntegTestCase { if (targetNodes.isEmpty()) { continue; } - - safeGet( - clusterAdmin().prepareReroute() - .add( - new MoveAllocationCommand( - shardId.getIndexName(), - shardId.id(), - indicesService.clusterService().localNode().getId(), - randomFrom(targetNodes) - ) - ) - .execute() + ClusterRerouteUtils.reroute( + client(), + new MoveAllocationCommand( + shardId.getIndexName(), + shardId.id(), + indicesService.clusterService().localNode().getId(), + randomFrom(targetNodes) + ) ); } } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 6e19cf60cf5b..d625b53785d3 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -12,6 +12,7 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionFuture; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; @@ -597,7 +598,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas Runnable fixupAction = () -> { // remove the shard allocation filtering settings and use the Reroute API to retry the failed shards updateIndexSettings(Settings.builder().putNull("index.routing.allocation.include._name"), indexName); - assertAcked(clusterAdmin().prepareReroute().setRetryFailed(true)); + ClusterRerouteUtils.rerouteRetryFailed(client()); }; unrestorableUseCase( diff --git a/server/src/main/java/org/elasticsearch/TransportVersions.java b/server/src/main/java/org/elasticsearch/TransportVersions.java index c2be2da12534..e85209c19d82 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersions.java +++ b/server/src/main/java/org/elasticsearch/TransportVersions.java @@ -188,6 +188,7 @@ public class TransportVersions { public static final TransportVersion RANK_DOC_IN_SHARD_FETCH_REQUEST = def(8_679_00_0); public static final TransportVersion SECURITY_SETTINGS_REQUEST_TIMEOUTS = def(8_680_00_0); public static final TransportVersion QUERY_RULE_CRUD_API_PUT = def(8_681_00_0); + public static final TransportVersion DROP_UNUSED_NODES_REQUESTS = def(8_682_00_0); /* * STOP! READ THIS FIRST! No, really, diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoRequest.java index ebf01feaaa89..51699c1f7dcd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/info/NodesInfoRequest.java @@ -11,6 +11,7 @@ package org.elasticsearch.action.admin.cluster.node.info; import org.elasticsearch.action.support.nodes.BaseNodesRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.UpdateForV9; import java.io.IOException; import java.util.Set; @@ -30,6 +31,7 @@ public final class NodesInfoRequest extends BaseNodesRequest { * @param in A stream input object. * @throws IOException if the stream cannot be deserialized. */ + @UpdateForV9 // this constructor is unused in v9 public NodesInfoRequest(StreamInput in) throws IOException { super(in); nodesInfoMetrics = new NodesInfoMetrics(in); @@ -111,6 +113,7 @@ public final class NodesInfoRequest extends BaseNodesRequest { return this; } + @UpdateForV9 // this method can just call localOnly() in v9 @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsRequest.java index c441c6daf89b..ff88bc5fcf46 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsRequest.java @@ -13,6 +13,7 @@ import org.elasticsearch.action.support.nodes.BaseNodesRequest; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.UpdateForV9; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; @@ -36,9 +37,9 @@ public class NodesStatsRequest extends BaseNodesRequest { nodesStatsRequestParameters = new NodesStatsRequestParameters(); } + @UpdateForV9 // this constructor is unused in v9 public NodesStatsRequest(StreamInput in) throws IOException { super(in); - nodesStatsRequestParameters = new NodesStatsRequestParameters(in); } @@ -178,6 +179,7 @@ public class NodesStatsRequest extends BaseNodesRequest { nodesStatsRequestParameters.setIncludeShardsStats(includeShardsStats); } + @UpdateForV9 // this method can just call localOnly() in v9 @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java index 402f3666c2e8..b245a752524e 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequest.java @@ -13,6 +13,7 @@ import org.elasticsearch.cluster.routing.allocation.command.AllocationCommand; import org.elasticsearch.cluster.routing.allocation.command.AllocationCommands; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.TimeValue; import java.io.IOException; import java.util.Objects; @@ -34,8 +35,8 @@ public class ClusterRerouteRequest extends AcknowledgedRequest { public ClusterRerouteRequestBuilder(ElasticsearchClient client) { - super(client, TransportClusterRerouteAction.TYPE, new ClusterRerouteRequest()); + super( + client, + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest( + MasterNodeRequest.TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT, + AcknowledgedRequest.DEFAULT_ACK_TIMEOUT + ) + ); } /** diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRequest.java index ca2ec4e5607e..bba669e07a70 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRequest.java @@ -11,6 +11,7 @@ package org.elasticsearch.action.admin.cluster.stats; import org.elasticsearch.action.support.nodes.BaseNodesRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.UpdateForV9; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; @@ -23,6 +24,7 @@ import java.util.Map; */ public class ClusterStatsRequest extends BaseNodesRequest { + @UpdateForV9 // this constructor is unused in v9 public ClusterStatsRequest(StreamInput in) throws IOException { super(in); } @@ -40,6 +42,7 @@ public class ClusterStatsRequest extends BaseNodesRequest { return new CancellableTask(id, type, action, "", parentTaskId, headers); } + @UpdateForV9 // this method can just call localOnly() in v9 @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java index f1b6faaca439..2a8fecde7ee9 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java @@ -9,6 +9,7 @@ package org.elasticsearch.action.admin.cluster.stats; import org.apache.lucene.store.AlreadyClosedException; +import org.elasticsearch.TransportVersions; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.FailedNodeException; @@ -32,6 +33,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.util.CancellableSingleObjectCache; import org.elasticsearch.common.util.concurrent.ListenableFuture; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.core.UpdateForV9; import org.elasticsearch.index.IndexService; import org.elasticsearch.index.engine.CommitStats; import org.elasticsearch.index.seqno.RetentionLeaseStats; @@ -167,7 +169,7 @@ public class TransportClusterStatsAction extends TransportNodesAction< @Override protected ClusterStatsNodeRequest newNodeRequest(ClusterStatsRequest request) { - return new ClusterStatsNodeRequest(request); + return new ClusterStatsNodeRequest(); } @Override @@ -251,18 +253,16 @@ public class TransportClusterStatsAction extends TransportNodesAction< ); } + @UpdateForV9 // this can be replaced with TransportRequest.Empty in v9 public static class ClusterStatsNodeRequest extends TransportRequest { - // TODO don't wrap the whole top-level request, it contains heavy and irrelevant DiscoveryNode things; see #100878 - ClusterStatsRequest request; + ClusterStatsNodeRequest() {} public ClusterStatsNodeRequest(StreamInput in) throws IOException { super(in); - request = new ClusterStatsRequest(in); - } - - ClusterStatsNodeRequest(ClusterStatsRequest request) { - this.request = request; + if (in.getTransportVersion().before(TransportVersions.DROP_UNUSED_NODES_REQUESTS)) { + new ClusterStatsRequest(in); + } } @Override @@ -273,7 +273,9 @@ public class TransportClusterStatsAction extends TransportNodesAction< @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - request.writeTo(out); + if (out.getTransportVersion().before(TransportVersions.DROP_UNUSED_NODES_REQUESTS)) { + new ClusterStatsRequest().writeTo(out); + } } } diff --git a/server/src/main/java/org/elasticsearch/action/search/DfsQueryPhase.java b/server/src/main/java/org/elasticsearch/action/search/DfsQueryPhase.java index c5c35b1980a5..9ddac7f13eb5 100644 --- a/server/src/main/java/org/elasticsearch/action/search/DfsQueryPhase.java +++ b/server/src/main/java/org/elasticsearch/action/search/DfsQueryPhase.java @@ -9,6 +9,7 @@ package org.elasticsearch.action.search; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.join.ScoreMode; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.index.query.NestedQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.search.SearchPhaseResult; @@ -152,7 +153,7 @@ final class DfsQueryPhase extends SearchPhase { scoreDocs.sort(Comparator.comparingInt(scoreDoc -> scoreDoc.doc)); String nestedPath = dfsKnnResults.getNestedPath(); QueryBuilder query = new KnnScoreDocQueryBuilder( - scoreDocs.toArray(new ScoreDoc[0]), + scoreDocs.toArray(Lucene.EMPTY_SCORE_DOCS), source.knnSearch().get(i).getField(), source.knnSearch().get(i).getQueryVector() ).boost(source.knnSearch().get(i).boost()).queryName(source.knnSearch().get(i).queryName()); diff --git a/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java b/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java index 1d3859b9038f..55c754545cbb 100644 --- a/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java +++ b/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java @@ -24,6 +24,7 @@ import org.apache.lucene.search.TotalHits.Relation; import org.apache.lucene.util.SetOnce; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.io.stream.DelayableWriteable; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.search.TopDocsAndMaxScore; import org.elasticsearch.common.util.Maps; import org.elasticsearch.common.util.concurrent.AtomicArray; @@ -66,7 +67,6 @@ import java.util.function.Supplier; import static org.elasticsearch.search.SearchService.DEFAULT_SIZE; public final class SearchPhaseController { - private static final ScoreDoc[] EMPTY_DOCS = new ScoreDoc[0]; private final BiFunction< Supplier, @@ -195,7 +195,7 @@ public final class SearchPhaseController { return SortedTopDocs.EMPTY; } final TopDocs mergedTopDocs = mergeTopDocs(topDocs, size, ignoreFrom ? 0 : from); - final ScoreDoc[] mergedScoreDocs = mergedTopDocs == null ? EMPTY_DOCS : mergedTopDocs.scoreDocs; + final ScoreDoc[] mergedScoreDocs = mergedTopDocs == null ? Lucene.EMPTY_SCORE_DOCS : mergedTopDocs.scoreDocs; ScoreDoc[] scoreDocs = mergedScoreDocs; int numSuggestDocs = 0; if (reducedCompletionSuggestions.isEmpty() == false) { @@ -907,6 +907,6 @@ public final class SearchPhaseController { Object[] collapseValues, int numberOfCompletionsSuggestions ) { - public static final SortedTopDocs EMPTY = new SortedTopDocs(EMPTY_DOCS, false, null, null, null, 0); + public static final SortedTopDocs EMPTY = new SortedTopDocs(Lucene.EMPTY_SCORE_DOCS, false, null, null, null, 0); } } diff --git a/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java b/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java index e2443566786a..45cb11869108 100644 --- a/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java +++ b/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java @@ -8,7 +8,6 @@ package org.elasticsearch.action.search; -import org.apache.lucene.search.TotalHits; import org.elasticsearch.TransportVersions; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.OriginalIndices; @@ -18,6 +17,7 @@ import org.elasticsearch.common.collect.Iterators; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.xcontent.ChunkedToXContentHelper; import org.elasticsearch.common.xcontent.ChunkedToXContentObject; @@ -1154,7 +1154,7 @@ public class SearchResponse extends ActionResponse implements ChunkedToXContentO // public for tests public static SearchResponse empty(Supplier tookInMillisSupplier, Clusters clusters) { return new SearchResponse( - SearchHits.empty(new TotalHits(0L, TotalHits.Relation.EQUAL_TO), Float.NaN), + SearchHits.empty(Lucene.TOTAL_HITS_EQUAL_TO_ZERO, Float.NaN), InternalAggregations.EMPTY, null, false, diff --git a/server/src/main/java/org/elasticsearch/action/search/SearchResponseMerger.java b/server/src/main/java/org/elasticsearch/action/search/SearchResponseMerger.java index ae8c749475c5..d393adc4e26d 100644 --- a/server/src/main/java/org/elasticsearch/action/search/SearchResponseMerger.java +++ b/server/src/main/java/org/elasticsearch/action/search/SearchResponseMerger.java @@ -18,6 +18,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.search.SearchPhaseController.TopDocsStats; import org.elasticsearch.action.search.SearchResponse.Clusters; import org.elasticsearch.action.search.TransportSearchAction.SearchTimeProvider; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.search.TopDocsAndMaxScore; import org.elasticsearch.core.Releasable; import org.elasticsearch.index.shard.ShardId; @@ -177,7 +178,7 @@ public final class SearchResponseMerger implements Releasable { final TotalHits totalHits; if (searchHits.getTotalHits() == null) { // in case we didn't track total hits, we get null from each cluster, but we need to set 0 eq to the TopDocs - totalHits = new TotalHits(0, TotalHits.Relation.EQUAL_TO); + totalHits = Lucene.TOTAL_HITS_EQUAL_TO_ZERO; assert trackTotalHits == null || trackTotalHits == false; trackTotalHits = false; } else { diff --git a/server/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesRequest.java b/server/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesRequest.java index 8a2e7684cadf..626cdb8046f5 100644 --- a/server/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesRequest.java +++ b/server/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesRequest.java @@ -39,6 +39,14 @@ public abstract class BaseNodesRequest private TimeValue timeout; + /** + * @deprecated {@link BaseNodesRequest} derivatives are quite heavyweight and should never need sending over the wire. Do not include + * the full top-level request directly in the node-level requests. Instead, copy the needed fields over to a dedicated node-level + * request. + * + * @see #100878 + */ + @Deprecated(forRemoval = true) protected BaseNodesRequest(StreamInput in) throws IOException { // A bare `BaseNodesRequest` is never sent over the wire, but several implementations send the full top-level request to each node // (wrapped up in another request). They shouldn't, but until we fix that we must keep this. See #100878. diff --git a/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java index d2ac07cf1647..4f24aa7b93f4 100644 --- a/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/internal/ClusterAdminClient.java @@ -203,14 +203,26 @@ public class ClusterAdminClient implements ElasticsearchClient { return new ClusterUpdateSettingsRequestBuilder(this); } + /** + * @deprecated use {@code ClusterRerouteUtils} in tests, or just run the action directly + */ + @Deprecated(forRemoval = true) // temporary compatibility shim public ActionFuture reroute(final ClusterRerouteRequest request) { return execute(TransportClusterRerouteAction.TYPE, request); } + /** + * @deprecated use {@code ClusterRerouteUtils} in tests, or just run the action directly + */ + @Deprecated(forRemoval = true) // temporary compatibility shim public void reroute(final ClusterRerouteRequest request, final ActionListener listener) { execute(TransportClusterRerouteAction.TYPE, request, listener); } + /** + * @deprecated use {@code ClusterRerouteUtils} in tests, or just run the action directly + */ + @Deprecated(forRemoval = true) // temporary compatibility shim public ClusterRerouteRequestBuilder prepareReroute() { return new ClusterRerouteRequestBuilder(this); } diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java b/server/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java index 106f4c1e4e38..9fb44e0106df 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java @@ -100,13 +100,6 @@ public record AutoExpandReplicas(int minReplicas, int maxReplicas, boolean enabl public int getDesiredNumberOfReplicas(IndexMetadata indexMetadata, RoutingAllocation allocation) { assert enabled : "should only be called when enabled"; - // Make sure in stateless auto-expand indices always have 1 replica to ensure all shard roles are always present - if (Objects.equals( - indexMetadata.getSettings().get(ExistingShardsAllocator.EXISTING_SHARDS_ALLOCATOR_SETTING.getKey()), - "stateless" - )) { - return 1; - } int numMatchingDataNodes = 0; for (DiscoveryNode discoveryNode : allocation.nodes().getDataNodes().values()) { Decision decision = allocation.deciders().shouldAutoExpandToNode(indexMetadata, discoveryNode, allocation); @@ -150,9 +143,22 @@ public record AutoExpandReplicas(int minReplicas, int maxReplicas, boolean enabl for (final IndexMetadata indexMetadata : metadata) { if (indexMetadata.getState() == IndexMetadata.State.OPEN || isIndexVerifiedBeforeClosed(indexMetadata)) { AutoExpandReplicas autoExpandReplicas = indexMetadata.getAutoExpandReplicas(); + // Make sure auto-expand is applied only when configured, and entirely disabled in stateless if (autoExpandReplicas.enabled() == false) { continue; } + // Special case for stateless indices: auto-expand is disabled, unless number_of_replicas has been set + // manually to 0 via index settings, which needs to be converted to 1. + if (Objects.equals( + indexMetadata.getSettings().get(ExistingShardsAllocator.EXISTING_SHARDS_ALLOCATOR_SETTING.getKey()), + "stateless" + )) { + if (indexMetadata.getNumberOfReplicas() == 0) { + nrReplicasChanged.computeIfAbsent(1, ArrayList::new).add(indexMetadata.getIndex().getName()); + } else { + continue; + } + } if (allocation == null) { allocation = allocationSupplier.get(); } diff --git a/server/src/main/java/org/elasticsearch/common/bytes/CompositeBytesReference.java b/server/src/main/java/org/elasticsearch/common/bytes/CompositeBytesReference.java index b63d722df9b4..65a3bf95336c 100644 --- a/server/src/main/java/org/elasticsearch/common/bytes/CompositeBytesReference.java +++ b/server/src/main/java/org/elasticsearch/common/bytes/CompositeBytesReference.java @@ -9,7 +9,6 @@ package org.elasticsearch.common.bytes; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.BytesRefIterator; import org.apache.lucene.util.RamUsageEstimator; @@ -172,18 +171,33 @@ public final class CompositeBytesReference extends AbstractBytesReference { @Override public BytesRef toBytesRef() { - BytesRefBuilder builder = new BytesRefBuilder(); - builder.grow(length()); + final byte[] result = new byte[length]; + int offset = 0; + for (BytesReference reference : references) { + if (reference.hasArray()) { + int len = reference.length(); + System.arraycopy(reference.array(), reference.arrayOffset(), result, offset, len); + offset += len; + } else { + offset = copyViaIterator(reference, result, offset); + } + } + assert offset == result.length; + return new BytesRef(result); + } + + private static int copyViaIterator(BytesReference reference, byte[] result, int offset) { BytesRef spare; - BytesRefIterator iterator = iterator(); + BytesRefIterator iterator = reference.iterator(); try { while ((spare = iterator.next()) != null) { - builder.append(spare); + System.arraycopy(spare.bytes, spare.offset, result, offset, spare.length); + offset += spare.length; } } catch (IOException ex) { throw new AssertionError("won't happen", ex); // this is really an error since we don't do IO in our bytesreferences } - return builder.toBytesRef(); + return offset; } @Override diff --git a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java index 31a4ca97aad6..36b3076c29a3 100644 --- a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java +++ b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java @@ -101,7 +101,10 @@ public class Lucene { public static final ScoreDoc[] EMPTY_SCORE_DOCS = new ScoreDoc[0]; - public static final TopDocs EMPTY_TOP_DOCS = new TopDocs(new TotalHits(0, TotalHits.Relation.EQUAL_TO), EMPTY_SCORE_DOCS); + public static final TotalHits TOTAL_HITS_EQUAL_TO_ZERO = new TotalHits(0, TotalHits.Relation.EQUAL_TO); + public static final TotalHits TOTAL_HITS_GREATER_OR_EQUAL_TO_ZERO = new TotalHits(0, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO); + + public static final TopDocs EMPTY_TOP_DOCS = new TopDocs(TOTAL_HITS_EQUAL_TO_ZERO, EMPTY_SCORE_DOCS); private Lucene() {} diff --git a/server/src/main/java/org/elasticsearch/common/util/set/Sets.java b/server/src/main/java/org/elasticsearch/common/util/set/Sets.java index 75e5717d41b9..5434dc91238c 100644 --- a/server/src/main/java/org/elasticsearch/common/util/set/Sets.java +++ b/server/src/main/java/org/elasticsearch/common/util/set/Sets.java @@ -135,6 +135,15 @@ public final class Sets { return union; } + @SafeVarargs + public static Set union(Set first, Set... others) { + Set union = new HashSet<>(first); + for (Set other : others) { + union.addAll(other); + } + return union; + } + /** * The intersection of two sets. Namely, the resulting set contains all the elements that are in both sets. * Neither input is mutated by this operation, an entirely new set is returned. diff --git a/server/src/main/java/org/elasticsearch/lucene/grouping/SinglePassGroupingCollector.java b/server/src/main/java/org/elasticsearch/lucene/grouping/SinglePassGroupingCollector.java index b11a034ce4e4..85682b9e4d50 100644 --- a/server/src/main/java/org/elasticsearch/lucene/grouping/SinglePassGroupingCollector.java +++ b/server/src/main/java/org/elasticsearch/lucene/grouping/SinglePassGroupingCollector.java @@ -36,6 +36,7 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.grouping.GroupSelector; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.util.Maps; import org.elasticsearch.core.Nullable; import org.elasticsearch.index.mapper.MappedFieldType; @@ -202,7 +203,7 @@ public class SinglePassGroupingCollector extends SimpleCollector { if (groupMap.size() <= groupOffset) { TotalHits totalHits = new TotalHits(totalHitCount, TotalHits.Relation.EQUAL_TO); - return new TopFieldGroups(groupField, totalHits, new ScoreDoc[0], groupSort.getSort(), new Object[0]); + return new TopFieldGroups(groupField, totalHits, Lucene.EMPTY_SCORE_DOCS, groupSort.getSort(), new Object[0]); } if (orderedGroups == null) { diff --git a/server/src/main/java/org/elasticsearch/lucene/grouping/TopFieldGroups.java b/server/src/main/java/org/elasticsearch/lucene/grouping/TopFieldGroups.java index 8e5efa8a880b..350c7d91e2e4 100644 --- a/server/src/main/java/org/elasticsearch/lucene/grouping/TopFieldGroups.java +++ b/server/src/main/java/org/elasticsearch/lucene/grouping/TopFieldGroups.java @@ -16,6 +16,7 @@ import org.apache.lucene.search.SortField; import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.search.TotalHits; import org.apache.lucene.util.PriorityQueue; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.util.CollectionUtils; import java.util.ArrayList; @@ -225,7 +226,7 @@ public final class TopFieldGroups extends TopFieldDocs { queue.pop(); } } - hits = hitList.toArray(new ScoreDoc[0]); + hits = hitList.toArray(Lucene.EMPTY_SCORE_DOCS); values = groupList.toArray(new Object[0]); } TotalHits totalHits = new TotalHits(totalHitCount, totalHitsRelation); diff --git a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java index f91b08439422..a17bc885f6b6 100644 --- a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java +++ b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java @@ -83,7 +83,7 @@ public abstract class BaseRestHandler implements RestHandler { // check if the query has any parameters that are not in the supported set (if declared) Set supported = allSupportedParameters(); if (supported != null) { - var allSupported = Sets.union(ALWAYS_SUPPORTED, supported); + var allSupported = Sets.union(RestResponse.RESPONSE_PARAMS, ALWAYS_SUPPORTED, supported); if (allSupported.containsAll(request.params().keySet()) == false) { Set unsupported = Sets.difference(request.params().keySet(), allSupported); throw new IllegalArgumentException(unrecognized(request, unsupported, allSupported, "parameter")); @@ -97,6 +97,7 @@ public abstract class BaseRestHandler implements RestHandler { // use a sorted set so the unconsumed parameters appear in a reliable sorted order final SortedSet unconsumedParams = request.unconsumedParams() .stream() + .filter(p -> RestResponse.RESPONSE_PARAMS.contains(p) == false) .filter(p -> responseParams(request.getRestApiVersion()).contains(p) == false) .collect(Collectors.toCollection(TreeSet::new)); diff --git a/server/src/main/java/org/elasticsearch/rest/RestResponse.java b/server/src/main/java/org/elasticsearch/rest/RestResponse.java index 8cc0e35a6480..5502ab1ba094 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestResponse.java +++ b/server/src/main/java/org/elasticsearch/rest/RestResponse.java @@ -37,6 +37,7 @@ import static org.elasticsearch.rest.RestController.ELASTIC_PRODUCT_HTTP_HEADER; public final class RestResponse implements Releasable { public static final String TEXT_CONTENT_TYPE = "text/plain; charset=UTF-8"; + public static final Set RESPONSE_PARAMS = Set.of("error_trace"); static final String STATUS = "status"; diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterRerouteAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterRerouteAction.java index 769877ac943e..efd6f3e7b62c 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterRerouteAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterRerouteAction.java @@ -9,6 +9,7 @@ package org.elasticsearch.rest.action.admin.cluster; import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; +import org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction; import org.elasticsearch.client.internal.node.NodeClient; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.routing.allocation.command.AllocationCommands; @@ -86,7 +87,11 @@ public class RestClusterRerouteAction extends BaseRestHandler { if (metric == null) { request.params().put("metric", DEFAULT_METRICS); } - return channel -> client.admin().cluster().reroute(clusterRerouteRequest, new RestRefCountedChunkedToXContentListener<>(channel)); + return channel -> client.execute( + TransportClusterRerouteAction.TYPE, + clusterRerouteRequest, + new RestRefCountedChunkedToXContentListener<>(channel) + ); } @Override @@ -95,12 +100,10 @@ public class RestClusterRerouteAction extends BaseRestHandler { } public static ClusterRerouteRequest createRequest(RestRequest request) throws IOException { - ClusterRerouteRequest clusterRerouteRequest = new ClusterRerouteRequest(); + final var clusterRerouteRequest = new ClusterRerouteRequest(getMasterNodeTimeout(request), getAckTimeout(request)); clusterRerouteRequest.dryRun(request.paramAsBoolean("dry_run", clusterRerouteRequest.dryRun())); clusterRerouteRequest.explain(request.paramAsBoolean("explain", clusterRerouteRequest.explain())); - clusterRerouteRequest.ackTimeout(getAckTimeout(request)); clusterRerouteRequest.setRetryFailed(request.paramAsBoolean("retry_failed", clusterRerouteRequest.isRetryFailed())); - clusterRerouteRequest.masterNodeTimeout(getMasterNodeTimeout(request)); request.applyContentParser(parser -> PARSER.parse(parser, clusterRerouteRequest, null)); return clusterRerouteRequest; } diff --git a/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java b/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java index f5d4a3d66be4..b071739321ea 100644 --- a/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java +++ b/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java @@ -13,6 +13,7 @@ import org.elasticsearch.script.field.vectors.DenseVector; import org.elasticsearch.script.field.vectors.DenseVectorDocValuesField; import java.io.IOException; +import java.util.HexFormat; import java.util.List; public class VectorScoreScriptUtils { @@ -65,6 +66,23 @@ public class VectorScoreScriptUtils { this.qvMagnitude = (float) Math.sqrt(queryMagnitude); field.getElementType().checkVectorBounds(validateValues); } + + /** + * Constructs a dense vector function used for byte-sized vectors. + * + * @param scoreScript The script in which this function was referenced. + * @param field The vector field. + * @param queryVector The query vector. + */ + public ByteDenseVectorFunction(ScoreScript scoreScript, DenseVectorDocValuesField field, byte[] queryVector) { + super(scoreScript, field); + this.queryVector = queryVector; + float queryMagnitude = 0.0f; + for (byte value : queryVector) { + queryMagnitude += value * value; + } + this.qvMagnitude = (float) Math.sqrt(queryMagnitude); + } } public static class FloatDenseVectorFunction extends DenseVectorFunction { @@ -116,6 +134,10 @@ public class VectorScoreScriptUtils { super(scoreScript, field, queryVector); } + public ByteL1Norm(ScoreScript scoreScript, DenseVectorDocValuesField field, byte[] queryVector) { + super(scoreScript, field, queryVector); + } + public double l1norm() { setNextVector(); return field.get().l1Norm(queryVector); @@ -138,11 +160,25 @@ public class VectorScoreScriptUtils { private final L1NormInterface function; - public L1Norm(ScoreScript scoreScript, List queryVector, String fieldName) { + @SuppressWarnings("unchecked") + public L1Norm(ScoreScript scoreScript, Object queryVector, String fieldName) { DenseVectorDocValuesField field = (DenseVectorDocValuesField) scoreScript.field(fieldName); function = switch (field.getElementType()) { - case BYTE -> new ByteL1Norm(scoreScript, field, queryVector); - case FLOAT -> new FloatL1Norm(scoreScript, field, queryVector); + case BYTE -> { + if (queryVector instanceof List) { + yield new ByteL1Norm(scoreScript, field, (List) queryVector); + } else if (queryVector instanceof String s) { + byte[] parsedQueryVector = HexFormat.of().parseHex(s); + yield new ByteL1Norm(scoreScript, field, parsedQueryVector); + } + throw new IllegalArgumentException("Unsupported input object for byte vectors: " + queryVector.getClass().getName()); + } + case FLOAT -> { + if (queryVector instanceof List) { + yield new FloatL1Norm(scoreScript, field, (List) queryVector); + } + throw new IllegalArgumentException("Unsupported input object for float vectors: " + queryVector.getClass().getName()); + } }; } @@ -162,6 +198,10 @@ public class VectorScoreScriptUtils { super(scoreScript, field, queryVector); } + public ByteL2Norm(ScoreScript scoreScript, DenseVectorDocValuesField field, byte[] queryVector) { + super(scoreScript, field, queryVector); + } + public double l2norm() { setNextVector(); return field.get().l2Norm(queryVector); @@ -184,11 +224,25 @@ public class VectorScoreScriptUtils { private final L2NormInterface function; - public L2Norm(ScoreScript scoreScript, List queryVector, String fieldName) { + @SuppressWarnings("unchecked") + public L2Norm(ScoreScript scoreScript, Object queryVector, String fieldName) { DenseVectorDocValuesField field = (DenseVectorDocValuesField) scoreScript.field(fieldName); function = switch (field.getElementType()) { - case BYTE -> new ByteL2Norm(scoreScript, field, queryVector); - case FLOAT -> new FloatL2Norm(scoreScript, field, queryVector); + case BYTE -> { + if (queryVector instanceof List) { + yield new ByteL2Norm(scoreScript, field, (List) queryVector); + } else if (queryVector instanceof String s) { + byte[] parsedQueryVector = HexFormat.of().parseHex(s); + yield new ByteL2Norm(scoreScript, field, parsedQueryVector); + } + throw new IllegalArgumentException("Unsupported input object for byte vectors: " + queryVector.getClass().getName()); + } + case FLOAT -> { + if (queryVector instanceof List) { + yield new FloatL2Norm(scoreScript, field, (List) queryVector); + } + throw new IllegalArgumentException("Unsupported input object for float vectors: " + queryVector.getClass().getName()); + } }; } @@ -208,6 +262,10 @@ public class VectorScoreScriptUtils { super(scoreScript, field, queryVector); } + public ByteDotProduct(ScoreScript scoreScript, DenseVectorDocValuesField field, byte[] queryVector) { + super(scoreScript, field, queryVector); + } + public double dotProduct() { setNextVector(); return field.get().dotProduct(queryVector); @@ -230,11 +288,25 @@ public class VectorScoreScriptUtils { private final DotProductInterface function; - public DotProduct(ScoreScript scoreScript, List queryVector, String fieldName) { + @SuppressWarnings("unchecked") + public DotProduct(ScoreScript scoreScript, Object queryVector, String fieldName) { DenseVectorDocValuesField field = (DenseVectorDocValuesField) scoreScript.field(fieldName); function = switch (field.getElementType()) { - case BYTE -> new ByteDotProduct(scoreScript, field, queryVector); - case FLOAT -> new FloatDotProduct(scoreScript, field, queryVector); + case BYTE -> { + if (queryVector instanceof List) { + yield new ByteDotProduct(scoreScript, field, (List) queryVector); + } else if (queryVector instanceof String s) { + byte[] parsedQueryVector = HexFormat.of().parseHex(s); + yield new ByteDotProduct(scoreScript, field, parsedQueryVector); + } + throw new IllegalArgumentException("Unsupported input object for byte vectors: " + queryVector.getClass().getName()); + } + case FLOAT -> { + if (queryVector instanceof List) { + yield new FloatDotProduct(scoreScript, field, (List) queryVector); + } + throw new IllegalArgumentException("Unsupported input object for float vectors: " + queryVector.getClass().getName()); + } }; } @@ -254,6 +326,10 @@ public class VectorScoreScriptUtils { super(scoreScript, field, queryVector); } + public ByteCosineSimilarity(ScoreScript scoreScript, DenseVectorDocValuesField field, byte[] queryVector) { + super(scoreScript, field, queryVector); + } + public double cosineSimilarity() { setNextVector(); return field.get().cosineSimilarity(queryVector, qvMagnitude); @@ -276,11 +352,25 @@ public class VectorScoreScriptUtils { private final CosineSimilarityInterface function; - public CosineSimilarity(ScoreScript scoreScript, List queryVector, String fieldName) { + @SuppressWarnings("unchecked") + public CosineSimilarity(ScoreScript scoreScript, Object queryVector, String fieldName) { DenseVectorDocValuesField field = (DenseVectorDocValuesField) scoreScript.field(fieldName); function = switch (field.getElementType()) { - case BYTE -> new ByteCosineSimilarity(scoreScript, field, queryVector); - case FLOAT -> new FloatCosineSimilarity(scoreScript, field, queryVector); + case BYTE -> { + if (queryVector instanceof List) { + yield new ByteCosineSimilarity(scoreScript, field, (List) queryVector); + } else if (queryVector instanceof String s) { + byte[] parsedQueryVector = HexFormat.of().parseHex(s); + yield new ByteCosineSimilarity(scoreScript, field, parsedQueryVector); + } + throw new IllegalArgumentException("Unsupported input object for byte vectors: " + queryVector.getClass().getName()); + } + case FLOAT -> { + if (queryVector instanceof List) { + yield new FloatCosineSimilarity(scoreScript, field, (List) queryVector); + } + throw new IllegalArgumentException("Unsupported input object for float vectors: " + queryVector.getClass().getName()); + } }; } diff --git a/server/src/main/java/org/elasticsearch/search/SearchHits.java b/server/src/main/java/org/elasticsearch/search/SearchHits.java index 15b83b202fd9..b2bc3097af18 100644 --- a/server/src/main/java/org/elasticsearch/search/SearchHits.java +++ b/server/src/main/java/org/elasticsearch/search/SearchHits.java @@ -34,7 +34,7 @@ import java.util.Objects; public final class SearchHits implements Writeable, ChunkedToXContent, RefCounted, Iterable { public static final SearchHit[] EMPTY = new SearchHit[0]; - public static final SearchHits EMPTY_WITH_TOTAL_HITS = SearchHits.empty(new TotalHits(0, Relation.EQUAL_TO), 0); + public static final SearchHits EMPTY_WITH_TOTAL_HITS = SearchHits.empty(Lucene.TOTAL_HITS_EQUAL_TO_ZERO, 0); public static final SearchHits EMPTY_WITHOUT_TOTAL_HITS = SearchHits.empty(null, 0); private final SearchHit[] hits; diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java index a3cf20d0b9b7..e61465fbc5e3 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java @@ -20,7 +20,6 @@ import org.apache.lucene.search.TopDocsCollector; import org.apache.lucene.search.TopFieldCollector; import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.search.TopScoreDocCollector; -import org.apache.lucene.search.TotalHits; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.search.MaxScoreCollector; import org.elasticsearch.common.lucene.Lucene; @@ -233,11 +232,7 @@ class TopHitsAggregator extends MetricsAggregator { public InternalTopHits buildEmptyAggregation() { TopDocs topDocs; if (subSearchContext.sort() != null) { - topDocs = new TopFieldDocs( - new TotalHits(0, TotalHits.Relation.EQUAL_TO), - new FieldDoc[0], - subSearchContext.sort().sort.getSort() - ); + topDocs = new TopFieldDocs(Lucene.TOTAL_HITS_EQUAL_TO_ZERO, new FieldDoc[0], subSearchContext.sort().sort.getSort()); } else { topDocs = Lucene.EMPTY_TOP_DOCS; } diff --git a/server/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java b/server/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java index 0263c6e83b17..cba2cf761e6f 100644 --- a/server/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java +++ b/server/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java @@ -49,7 +49,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.PriorityQueue; @@ -255,13 +254,11 @@ public class ContextIndexSearcher extends IndexSearcher implements Releasable { // Make a copy so we can sort: List sortedLeaves = new ArrayList<>(leaves); // Sort by maxDoc, descending: - final Comparator leafComparator = Comparator.comparingInt(l -> l.reader().maxDoc()); - sortedLeaves.sort(leafComparator.reversed()); + sortedLeaves.sort((c1, c2) -> Integer.compare(c2.reader().maxDoc(), c1.reader().maxDoc())); // we add the groups on a priority queue, so we can add orphan leafs to the smallest group - final Comparator> groupComparator = Comparator.comparingInt( - l -> l.stream().mapToInt(lr -> lr.reader().maxDoc()).sum() + final PriorityQueue> queue = new PriorityQueue<>( + (c1, c2) -> Integer.compare(sumMaxDocValues(c1), sumMaxDocValues(c2)) ); - final PriorityQueue> queue = new PriorityQueue<>(groupComparator); long docSum = 0; List group = new ArrayList<>(); for (LeafReaderContext ctx : sortedLeaves) { @@ -297,6 +294,14 @@ public class ContextIndexSearcher extends IndexSearcher implements Releasable { return slices; } + private static int sumMaxDocValues(List l) { + int sum = 0; + for (LeafReaderContext lr : l) { + sum += lr.reader().maxDoc(); + } + return sum; + } + @Override public T search(Query query, CollectorManager collectorManager) throws IOException { final C firstCollector = collectorManager.newCollector(); @@ -337,7 +342,7 @@ public class ContextIndexSearcher extends IndexSearcher implements Releasable { throw new IllegalStateException("CollectorManager does not always produce collectors with the same score mode"); } } - final List> listTasks = new ArrayList<>(); + final List> listTasks = new ArrayList<>(leafSlices.length); for (int i = 0; i < leafSlices.length; ++i) { final LeafReaderContext[] leaves = leafSlices[i].leaves; final C collector = collectors.get(i); diff --git a/server/src/main/java/org/elasticsearch/search/query/QueryPhase.java b/server/src/main/java/org/elasticsearch/search/query/QueryPhase.java index 0d2610aa3428..af0240e9497f 100644 --- a/server/src/main/java/org/elasticsearch/search/query/QueryPhase.java +++ b/server/src/main/java/org/elasticsearch/search/query/QueryPhase.java @@ -22,7 +22,6 @@ import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.ScoreMode; import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.Weight; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.search.TopDocsAndMaxScore; @@ -76,11 +75,7 @@ public class QueryPhase { searchContext.size(0); QueryPhase.executeQuery(searchContext); } else { - searchContext.queryResult() - .topDocs( - new TopDocsAndMaxScore(new TopDocs(new TotalHits(0, TotalHits.Relation.EQUAL_TO), Lucene.EMPTY_SCORE_DOCS), Float.NaN), - new DocValueFormat[0] - ); + searchContext.queryResult().topDocs(new TopDocsAndMaxScore(Lucene.EMPTY_TOP_DOCS, Float.NaN), new DocValueFormat[0]); } List rrfRankResults = new ArrayList<>(); @@ -124,11 +119,7 @@ public class QueryPhase { static void executeQuery(SearchContext searchContext) throws QueryPhaseExecutionException { if (searchContext.hasOnlySuggest()) { SuggestPhase.execute(searchContext); - searchContext.queryResult() - .topDocs( - new TopDocsAndMaxScore(new TopDocs(new TotalHits(0, TotalHits.Relation.EQUAL_TO), Lucene.EMPTY_SCORE_DOCS), Float.NaN), - new DocValueFormat[0] - ); + searchContext.queryResult().topDocs(new TopDocsAndMaxScore(Lucene.EMPTY_TOP_DOCS, Float.NaN), new DocValueFormat[0]); return; } diff --git a/server/src/main/java/org/elasticsearch/search/query/QueryPhaseCollectorManager.java b/server/src/main/java/org/elasticsearch/search/query/QueryPhaseCollectorManager.java index 2286eb2e69f8..22b5f3d8dcaf 100644 --- a/server/src/main/java/org/elasticsearch/search/query/QueryPhaseCollectorManager.java +++ b/server/src/main/java/org/elasticsearch/search/query/QueryPhaseCollectorManager.java @@ -400,7 +400,7 @@ abstract class QueryPhaseCollectorManager implements CollectorManager { - private String requestName; - - private CancellableNodesRequest(StreamInput in) throws IOException { - super(in); - requestName = in.readString(); - } + private final String requestName; public CancellableNodesRequest(String requestName, String... nodesIds) { super(nodesIds); @@ -147,7 +142,7 @@ public class CancellableTasksTests extends TaskManagerTestCase { boolean shouldBlock, CountDownLatch actionStartedLatch ) { - super(actionName, threadPool, clusterService, transportService, CancellableNodesRequest::new, CancellableNodeRequest::new); + super(actionName, threadPool, clusterService, transportService, CancellableNodeRequest::new); this.shouldBlock = shouldBlock; this.actionStartedLatch = actionStartedLatch; } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java index f943ff14002c..f3450bbff669 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TaskManagerTestCase.java @@ -144,7 +144,6 @@ public abstract class TaskManagerTestCase extends ESTestCase { ThreadPool threadPool, ClusterService clusterService, TransportService transportService, - Writeable.Reader request, Writeable.Reader nodeRequest ) { super( diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java index 63629e16974d..6f345eb7dcda 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java @@ -195,19 +195,11 @@ public class TestTaskPlugin extends Plugin implements ActionPlugin, NetworkPlugi } public static class NodesRequest extends BaseNodesRequest { - private String requestName; + private final String requestName; private boolean shouldStoreResult = false; private boolean shouldBlock = true; private boolean shouldFail = false; - NodesRequest(StreamInput in) throws IOException { - super(in); - requestName = in.readString(); - shouldStoreResult = in.readBoolean(); - shouldBlock = in.readBoolean(); - shouldFail = in.readBoolean(); - } - NodesRequest(String requestName, String... nodesIds) { super(nodesIds); this.requestName = requestName; diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TransportTasksActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TransportTasksActionTests.java index 6f4da1fe1ebe..969ed50685bc 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TransportTasksActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TransportTasksActionTests.java @@ -109,11 +109,6 @@ public class TransportTasksActionTests extends TaskManagerTestCase { public static class NodesRequest extends BaseNodesRequest { private final String requestName; - NodesRequest(StreamInput in) throws IOException { - super(in); - requestName = in.readString(); - } - public NodesRequest(String requestName, String... nodesIds) { super(nodesIds); this.requestName = requestName; @@ -142,7 +137,7 @@ public class TransportTasksActionTests extends TaskManagerTestCase { abstract class TestNodesAction extends AbstractTestNodesAction { TestNodesAction(String actionName, ThreadPool threadPool, ClusterService clusterService, TransportService transportService) { - super(actionName, threadPool, clusterService, transportService, NodesRequest::new, NodeRequest::new); + super(actionName, threadPool, clusterService, transportService, NodeRequest::new); } @Override diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequestTests.java index 7ccdb5da6d73..5c39275abbcf 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteRequestTests.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.network.NetworkModule; -import org.elasticsearch.core.TimeValue; import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.RestUtils; import org.elasticsearch.rest.action.admin.cluster.RestClusterRerouteAction; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.rest.FakeRestRequest; @@ -38,6 +38,7 @@ import java.util.List; import java.util.Map; import java.util.function.Supplier; +import static org.elasticsearch.action.support.master.AcknowledgedRequest.DEFAULT_ACK_TIMEOUT; import static org.elasticsearch.core.TimeValue.timeValueMillis; import static org.elasticsearch.rest.RestUtils.REST_MASTER_TIMEOUT_PARAM; @@ -80,7 +81,7 @@ public class ClusterRerouteRequestTests extends ESTestCase { } private ClusterRerouteRequest randomRequest() { - ClusterRerouteRequest request = new ClusterRerouteRequest(); + ClusterRerouteRequest request = new ClusterRerouteRequest(randomTimeValue(), randomTimeValue()); int commands = between(0, 10); for (int i = 0; i < commands; i++) { request.add(randomFrom(RANDOM_COMMAND_GENERATORS).get()); @@ -97,7 +98,7 @@ public class ClusterRerouteRequestTests extends ESTestCase { assertEquals(request, request); assertEquals(request.hashCode(), request.hashCode()); - ClusterRerouteRequest copy = new ClusterRerouteRequest().add( + ClusterRerouteRequest copy = new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).add( request.getCommands().commands().toArray(new AllocationCommand[0]) ); AcknowledgedRequest clusterRerouteRequestAcknowledgedRequest = copy.dryRun(request.dryRun()) @@ -196,14 +197,14 @@ public class ClusterRerouteRequestTests extends ESTestCase { builder.field("dry_run", original.dryRun()); } params.put("explain", Boolean.toString(original.explain())); - if (false == original.ackTimeout().equals(AcknowledgedRequest.DEFAULT_ACK_TIMEOUT) || randomBoolean()) { - params.put("timeout", original.ackTimeout().toString()); + if (false == original.ackTimeout().equals(DEFAULT_ACK_TIMEOUT) || randomBoolean()) { + params.put("timeout", original.ackTimeout().getStringRep()); } if (original.isRetryFailed() || randomBoolean()) { params.put("retry_failed", Boolean.toString(original.isRetryFailed())); } - if (false == original.masterNodeTimeout().equals(TimeValue.THIRTY_SECONDS) || randomBoolean()) { - params.put(REST_MASTER_TIMEOUT_PARAM, original.masterNodeTimeout().toString()); + if (false == original.masterNodeTimeout().equals(RestUtils.REST_MASTER_TIMEOUT_DEFAULT) || randomBoolean()) { + params.put(REST_MASTER_TIMEOUT_PARAM, original.masterNodeTimeout().getStringRep()); } if (original.getCommands() != null) { hasBody = true; diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteTests.java index 19c268100d4a..d2eb8d958bf8 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteTests.java @@ -51,7 +51,7 @@ import static org.hamcrest.Matchers.not; public class ClusterRerouteTests extends ESAllocationTestCase { public void testSerializeRequest() throws IOException { - ClusterRerouteRequest req = new ClusterRerouteRequest(); + ClusterRerouteRequest req = new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT); req.setRetryFailed(randomBoolean()); req.dryRun(randomBoolean()); req.explain(randomBoolean()); @@ -86,7 +86,7 @@ public class ClusterRerouteTests extends ESAllocationTestCase { var responseRef = new AtomicReference(); var responseActionListener = ActionTestUtils.assertNoFailureListener(responseRef::set); - var request = new ClusterRerouteRequest().dryRun(true); + var request = new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).dryRun(true); var task = new TransportClusterRerouteAction.ClusterRerouteResponseAckedClusterStateUpdateTask( logger, allocationService, @@ -112,7 +112,7 @@ public class ClusterRerouteTests extends ESAllocationTestCase { ); ClusterState clusterState = createInitialClusterState(allocationService); - var req = new ClusterRerouteRequest().dryRun(false); + var req = new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).dryRun(false); var task = new TransportClusterRerouteAction.ClusterRerouteResponseAckedClusterStateUpdateTask( logger, allocationService, diff --git a/server/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java b/server/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java index 689040f9b6c5..d0535665d368 100644 --- a/server/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java +++ b/server/src/test/java/org/elasticsearch/action/support/nodes/TransportNodesActionTests.java @@ -323,11 +323,9 @@ public class TransportNodesActionTests extends ESTestCase { public DataNodesOnlyTransportNodesAction getDataNodesOnlyTransportNodesAction(TransportService transportService) { return new DataNodesOnlyTransportNodesAction( - THREAD_POOL, clusterService, transportService, new ActionFilters(Collections.emptySet()), - TestNodesRequest::new, TestNodeRequest::new, THREAD_POOL.executor(ThreadPool.Names.GENERIC) ); @@ -383,11 +381,9 @@ public class TransportNodesActionTests extends ESTestCase { private static class DataNodesOnlyTransportNodesAction extends TestTransportNodesAction { DataNodesOnlyTransportNodesAction( - ThreadPool threadPool, ClusterService clusterService, TransportService transportService, ActionFilters actionFilters, - Writeable.Reader request, Writeable.Reader nodeRequest, Executor nodeExecutor ) { @@ -401,10 +397,6 @@ public class TransportNodesActionTests extends ESTestCase { } private static class TestNodesRequest extends BaseNodesRequest { - TestNodesRequest(StreamInput in) throws IOException { - super(in); - } - TestNodesRequest(String... nodesIds) { super(nodesIds); } diff --git a/server/src/test/java/org/elasticsearch/client/internal/AbstractClientHeadersTestCase.java b/server/src/test/java/org/elasticsearch/client/internal/AbstractClientHeadersTestCase.java index dc0bd57731d9..652e7f014b8e 100644 --- a/server/src/test/java/org/elasticsearch/client/internal/AbstractClientHeadersTestCase.java +++ b/server/src/test/java/org/elasticsearch/client/internal/AbstractClientHeadersTestCase.java @@ -11,6 +11,7 @@ package org.elasticsearch.client.internal; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; import org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction; import org.elasticsearch.action.admin.cluster.snapshots.create.TransportCreateSnapshotAction; import org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction; @@ -118,10 +119,11 @@ public abstract class AbstractClientHeadersTestCase extends ESTestCase { .cluster() .prepareCreateSnapshot("repo", "bck") .execute(new AssertingActionListener<>(TransportCreateSnapshotAction.TYPE.name(), client.threadPool())); - client.admin() - .cluster() - .prepareReroute() - .execute(new AssertingActionListener<>(TransportClusterRerouteAction.TYPE.name(), client.threadPool())); + client.execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT), + new AssertingActionListener<>(TransportClusterRerouteAction.TYPE.name(), client.threadPool()) + ); // choosing arbitrary indices admin actions to test client.admin() diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/AutoExpandReplicasTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/AutoExpandReplicasTests.java index 1ca7333c90a2..8a13d0cdc14f 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/AutoExpandReplicasTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/AutoExpandReplicasTests.java @@ -142,7 +142,7 @@ public class AutoExpandReplicasTests extends ESTestCase { state, state.routingTable().index("index").shard(0).shardsWithState(ShardRoutingState.INITIALIZING) ); - state = cluster.reroute(state, new ClusterRerouteRequest()); + state = cluster.reroute(state, new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT)); } IndexShardRoutingTable preTable = state.routingTable().index("index").shard(0); diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/FailedNodeRoutingTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/FailedNodeRoutingTests.java index d76e9912cef0..608c81417531 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/FailedNodeRoutingTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/FailedNodeRoutingTests.java @@ -123,7 +123,8 @@ public class FailedNodeRoutingTests extends ESAllocationTestCase { for (int i = 0; i < randomIntBetween(4, 8); i++) { DiscoveryNodes newNodes = DiscoveryNodes.builder(state.nodes()).add(createNode()).build(); state = ClusterState.builder(state).nodes(newNodes).build(); - state = cluster.reroute(state, new ClusterRerouteRequest()); // always reroute after adding node + // always reroute after adding node + state = cluster.reroute(state, new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT)); } // Log the node versions (for debugging if necessary) diff --git a/server/src/test/java/org/elasticsearch/indices/cluster/IndicesClusterStateServiceRandomUpdatesTests.java b/server/src/test/java/org/elasticsearch/indices/cluster/IndicesClusterStateServiceRandomUpdatesTests.java index 1ace9a786cca..0ebcbff6bf86 100644 --- a/server/src/test/java/org/elasticsearch/indices/cluster/IndicesClusterStateServiceRandomUpdatesTests.java +++ b/server/src/test/java/org/elasticsearch/indices/cluster/IndicesClusterStateServiceRandomUpdatesTests.java @@ -441,7 +441,7 @@ public class IndicesClusterStateServiceRandomUpdatesTests extends AbstractIndice // randomly reroute if (rarely()) { - state = cluster.reroute(state, new ClusterRerouteRequest()); + state = cluster.reroute(state, new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT)); } // randomly start and fail allocated shards diff --git a/server/src/test/java/org/elasticsearch/rest/BaseRestHandlerTests.java b/server/src/test/java/org/elasticsearch/rest/BaseRestHandlerTests.java index b5c6b28693b3..2318614c241e 100644 --- a/server/src/test/java/org/elasticsearch/rest/BaseRestHandlerTests.java +++ b/server/src/test/java/org/elasticsearch/rest/BaseRestHandlerTests.java @@ -235,6 +235,7 @@ public class BaseRestHandlerTests extends ESTestCase { params.put("filter_path", randomAlphaOfLength(8)); params.put("pretty", randomFrom("true", "false", "", null)); params.put("human", null); + params.put("error_trace", randomFrom("true", "false", null)); RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withParams(params).build(); RestChannel channel = new FakeRestChannel(request, randomBoolean(), 1); handler.handleRequest(request, channel, mockClient); diff --git a/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java b/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java index df9f4384719e..a095c4e6409a 100644 --- a/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java +++ b/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java @@ -26,6 +26,7 @@ import org.elasticsearch.test.ESTestCase; import java.io.IOException; import java.util.Arrays; +import java.util.HexFormat; import java.util.List; import static org.hamcrest.Matchers.containsString; @@ -128,6 +129,7 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { float[] docVector = new float[] { 1, 127, -128, 5, -10 }; List queryVector = Arrays.asList((byte) 1, (byte) 125, (byte) -12, (byte) 2, (byte) 4); List invalidQueryVector = Arrays.asList((byte) 1, (byte) 1); + String hexidecimalString = HexFormat.of().formatHex(new byte[] { 1, 125, -12, 2, 4 }); List fields = List.of( new ByteBinaryDenseVectorDocValuesField( @@ -154,6 +156,14 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { 0.001 ); + function = new CosineSimilarity(scoreScript, hexidecimalString, fieldName); + assertEquals( + "cosineSimilarity result is not equal to the expected value!", + cosineSimilarityExpected, + function.cosineSimilarity(), + 0.001 + ); + // Test normalization for cosineSimilarity float[] queryVectorArray = new float[queryVector.size()]; for (int i = 0; i < queryVectorArray.length; i++) { @@ -191,10 +201,13 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { ); // Check scripting infrastructure integration - DotProduct dotProduct = new DotProduct(scoreScript, queryVector, fieldName); - assertEquals(17382.0, dotProduct.dotProduct(), 0.001); + assertEquals(17382.0, new DotProduct(scoreScript, queryVector, fieldName).dotProduct(), 0.001); + assertEquals(17382.0, new DotProduct(scoreScript, hexidecimalString, fieldName).dotProduct(), 0.001); assertEquals(135.0, new L1Norm(scoreScript, queryVector, fieldName).l1norm(), 0.001); + assertEquals(135.0, new L1Norm(scoreScript, hexidecimalString, fieldName).l1norm(), 0.001); assertEquals(116.897, new L2Norm(scoreScript, queryVector, fieldName).l2norm(), 0.001); + assertEquals(116.897, new L2Norm(scoreScript, hexidecimalString, fieldName).l2norm(), 0.001); + DotProduct dotProduct = new DotProduct(scoreScript, queryVector, fieldName); when(scoreScript._getDocId()).thenReturn(1); e = expectThrows(IllegalArgumentException.class, dotProduct::dotProduct); assertEquals("A document doesn't have a value for a vector field!", e.getMessage()); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 40064e2b68ed..cbdb30652f96 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -1050,19 +1050,18 @@ public class SnapshotResiliencyTests extends ESTestCase { .deleteSnapshot(new DeleteSnapshotRequest(repoName, snapshotName), ActionListener.noop()); })); scheduleNow( - () -> testClusterNodes.randomMasterNodeSafe().client.admin() - .cluster() - .reroute( - new ClusterRerouteRequest().add( - new AllocateEmptyPrimaryAllocationCommand( - index, - shardRouting.shardId().id(), - otherNode.node.getName(), - true - ) - ), - ActionListener.noop() - ) + () -> testClusterNodes.randomMasterNodeSafe().client.execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).add( + new AllocateEmptyPrimaryAllocationCommand( + index, + shardRouting.shardId().id(), + otherNode.node.getName(), + true + ) + ), + ActionListener.noop() + ) ); } else { scheduleSoon(this); diff --git a/test/external-modules/seek-tracking-directory/build.gradle b/test/external-modules/seek-tracking-directory/build.gradle deleted file mode 100644 index 596ea540de81..000000000000 --- a/test/external-modules/seek-tracking-directory/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -esplugin { - description 'A test module that tracks seeks in lucene Directories' - classname 'org.elasticsearch.test.seektracker.SeekTrackerPlugin' -} - -apply plugin: 'elasticsearch.internal-cluster-test' diff --git a/test/external-modules/seek-tracking-directory/src/internalClusterTest/java/org/elasticsearch/test/seektracker/SeekTrackerPluginIT.java b/test/external-modules/seek-tracking-directory/src/internalClusterTest/java/org/elasticsearch/test/seektracker/SeekTrackerPluginIT.java deleted file mode 100644 index 7d1e4c4c3d0d..000000000000 --- a/test/external-modules/seek-tracking-directory/src/internalClusterTest/java/org/elasticsearch/test/seektracker/SeekTrackerPluginIT.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.action.index.IndexRequestBuilder; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.test.ESIntegTestCase; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; -import static org.hamcrest.Matchers.greaterThan; - -public class SeekTrackerPluginIT extends ESIntegTestCase { - - @Override - protected Collection> nodePlugins() { - return List.of(SeekTrackerPlugin.class); - } - - @Override - protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) { - return Settings.builder() - .put(super.nodeSettings(nodeOrdinal, otherSettings)) - .put(SeekTrackerPlugin.SEEK_TRACKING_ENABLED.getKey(), "true") - .build(); - } - - public void testSeekTrackerPlugin() throws InterruptedException { - - assertAcked(indicesAdmin().prepareCreate("index")); - List docs = new ArrayList<>(); - for (int i = 0; i < 100; i++) { - docs.add(prepareIndex("index").setSource("field", "term" + i % 5)); - } - indexRandom(true, docs); - - prepareSearch("index").setQuery(QueryBuilders.termQuery("field", "term2")).get().decRef(); - - SeekStatsResponse response = client().execute(SeekTrackerPlugin.SEEK_STATS_ACTION, new SeekStatsRequest("index")).actionGet(); - List shardSeekStats = response.getSeekStats().get("index"); - assertThat(shardSeekStats.size(), greaterThan(0)); - } - -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/IndexSeekTracker.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/IndexSeekTracker.java deleted file mode 100644 index 2cb3fa4bbe6a..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/IndexSeekTracker.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.LongAdder; - -public class IndexSeekTracker { - - private final String index; - private final Map> seeks = new HashMap<>(); - - public IndexSeekTracker(String index) { - this.index = index; - } - - public void track(String shard) { - seeks.computeIfAbsent(shard, k -> new ConcurrentHashMap<>()); // increment can be called by multiple threads - } - - public void increment(String shard, String file) { - seeks.get(shard).computeIfAbsent(file, s -> new LongAdder()).increment(); - } - - public List getSeeks() { - List values = new ArrayList<>(); - seeks.forEach((k, v) -> values.add(getSeeksForShard(k))); - return values; - } - - private ShardSeekStats getSeeksForShard(String shard) { - Map seeksPerFile = new HashMap<>(); - seeks.get(shard).forEach((name, adder) -> seeksPerFile.put(name, adder.longValue())); - return new ShardSeekStats(shard, seeksPerFile); - } - - @Override - public String toString() { - return "seeks for " + index + ": " + seeks; - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/NodeSeekStats.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/NodeSeekStats.java deleted file mode 100644 index 8b2d95c3cf57..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/NodeSeekStats.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.ToXContentFragment; -import org.elasticsearch.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -public class NodeSeekStats extends BaseNodeResponse implements ToXContentFragment { - - private final Map> seeks; - - public NodeSeekStats(DiscoveryNode node, Map> seeks) { - super(node); - this.seeks = seeks; - } - - public NodeSeekStats(StreamInput in) throws IOException { - super(in); - this.seeks = in.readMap(s -> s.readCollectionAsList(ShardSeekStats::new)); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeMap(seeks, StreamOutput::writeCollection); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { - builder.mapContents(seeks); - return builder; - } - - public Map> getSeekStats() { - return seeks; - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/RestSeekStatsAction.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/RestSeekStatsAction.java deleted file mode 100644 index 8695a08ce06a..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/RestSeekStatsAction.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.client.internal.node.NodeClient; -import org.elasticsearch.common.Strings; -import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.RestHandler; -import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.RestToXContentListener; - -import java.util.List; - -public class RestSeekStatsAction extends BaseRestHandler { - - @Override - public String getName() { - return "seek_stats_action"; - } - - @Override - public List routes() { - return List.of( - new RestHandler.Route(RestRequest.Method.GET, "/_seek_stats"), - new RestHandler.Route(RestRequest.Method.GET, "/{index}/_seek_stats") - ); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { - String[] indices = request.paramAsStringArray("index", Strings.EMPTY_ARRAY); - SeekStatsRequest seekStatsRequest = new SeekStatsRequest(indices); - return channel -> client.execute(SeekTrackerPlugin.SEEK_STATS_ACTION, seekStatsRequest, new RestToXContentListener<>(channel)); - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsRequest.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsRequest.java deleted file mode 100644 index 86dc35cc3cd4..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsRequest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; - -public class SeekStatsRequest extends BaseNodesRequest { - - private final String[] indices; - - public SeekStatsRequest(String... indices) { - super(Strings.EMPTY_ARRAY); - this.indices = indices; - } - - public SeekStatsRequest(StreamInput in) throws IOException { - super(in); - this.indices = in.readStringArray(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeStringArray(indices); - } - - public String[] getIndices() { - return indices; - } - -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsResponse.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsResponse.java deleted file mode 100644 index 27c28345091e..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsResponse.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.TransportAction; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.ToXContentObject; -import org.elasticsearch.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class SeekStatsResponse extends BaseNodesResponse implements ToXContentObject { - - public SeekStatsResponse(ClusterName clusterName, List seekStats, List failures) { - super(clusterName, seekStats, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) { - return TransportAction.localOnly(); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) { - TransportAction.localOnly(); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { - builder.startObject(); - for (NodeSeekStats seekStats : getNodes()) { - builder.startObject(seekStats.getNode().getId()); - seekStats.toXContent(builder, params); - builder.endObject(); - } - builder.endObject(); - return builder; - } - - public Map> getSeekStats() { - Map> combined = new HashMap<>(); - for (NodeSeekStats nodeSeekStats : getNodes()) { - nodeSeekStats.getSeekStats() - .forEach((index, shardSeekStats) -> combined.computeIfAbsent(index, k -> new ArrayList<>()).addAll(shardSeekStats)); - } - return combined; - } - - @Override - public String toString() { - return Strings.toString(this); - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsService.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsService.java deleted file mode 100644 index d98d87ab87ff..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekStatsService.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import java.util.HashMap; -import java.util.Map; - -public class SeekStatsService { - - private final Map seeks = new HashMap<>(); - - public IndexSeekTracker registerIndex(String index) { - return seeks.computeIfAbsent(index, IndexSeekTracker::new); - } - - public Map getSeekStats() { - return seeks; - } - - public IndexSeekTracker getSeekStats(String index) { - return seeks.get(index); - } - -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java deleted file mode 100644 index 54ef53b8969e..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackerPlugin.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.action.ActionType; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.cluster.node.DiscoveryNodes; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.settings.ClusterSettings; -import org.elasticsearch.common.settings.IndexScopedSettings; -import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsFilter; -import org.elasticsearch.features.NodeFeature; -import org.elasticsearch.index.IndexModule; -import org.elasticsearch.plugins.ActionPlugin; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.rest.RestController; -import org.elasticsearch.rest.RestHandler; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; -import java.util.function.Supplier; - -public class SeekTrackerPlugin extends Plugin implements ActionPlugin { - - /** Setting for enabling or disabling seek tracking. Defaults to false. */ - public static final Setting SEEK_TRACKING_ENABLED = Setting.boolSetting( - "seektracker.enabled", - false, - Setting.Property.NodeScope - ); - - public static final ActionType SEEK_STATS_ACTION = new ActionType<>("cluster:monitor/seek_stats"); - - private final SeekStatsService seekStatsService = new SeekStatsService(); - private final boolean enabled; - - public SeekTrackerPlugin(Settings settings) { - this.enabled = SEEK_TRACKING_ENABLED.get(settings); - } - - @Override - public List> getSettings() { - return List.of(SEEK_TRACKING_ENABLED); - } - - @Override - public Collection createComponents(PluginServices services) { - return Collections.singletonList(seekStatsService); - } - - // seeks per index/shard/file - - @Override - public void onIndexModule(IndexModule indexModule) { - if (enabled) { - IndexSeekTracker seekTracker = seekStatsService.registerIndex(indexModule.getIndex().getName()); - indexModule.setDirectoryWrapper(new SeekTrackingDirectoryWrapper(seekTracker)); - } - } - - @Override - public List getRestHandlers( - Settings settings, - NamedWriteableRegistry namedWriteableRegistry, - RestController restController, - ClusterSettings clusterSettings, - IndexScopedSettings indexScopedSettings, - SettingsFilter settingsFilter, - IndexNameExpressionResolver indexNameExpressionResolver, - Supplier nodesInCluster, - Predicate clusterSupportsFeature - ) { - if (enabled) { - return Collections.singletonList(new RestSeekStatsAction()); - } else { - return Collections.emptyList(); - } - } - - @Override - public List> getActions() { - if (enabled) { - return Collections.singletonList(new ActionHandler<>(SEEK_STATS_ACTION, TransportSeekStatsAction.class)); - } else { - return Collections.emptyList(); - } - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackingDirectoryWrapper.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackingDirectoryWrapper.java deleted file mode 100644 index 9b3d31022c58..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/SeekTrackingDirectoryWrapper.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.FilterDirectory; -import org.apache.lucene.store.IOContext; -import org.apache.lucene.store.IndexInput; -import org.apache.lucene.store.RandomAccessInput; -import org.elasticsearch.cluster.routing.ShardRouting; -import org.elasticsearch.index.IndexModule; - -import java.io.IOException; -import java.util.Map; -import java.util.Set; - -public class SeekTrackingDirectoryWrapper implements IndexModule.DirectoryWrapper { - - private final IndexSeekTracker seekTracker; - - public SeekTrackingDirectoryWrapper(IndexSeekTracker seekTracker) { - this.seekTracker = seekTracker; - } - - @Override - public Directory wrap(Directory directory, ShardRouting shardRouting) { - seekTracker.track(shardRouting.shardId().toString()); - return new FilterDirectory(directory) { - @Override - public IndexInput openInput(String name, IOContext context) throws IOException { - IndexInput input = super.openInput(name, context); - if (input instanceof RandomAccessInput) { - return new RandomAccessSeekCountingIndexInput(input, shardRouting.shardId().toString(), name); - } - return wrapIndexInput(shardRouting.shardId().toString(), name, input); - } - }; - } - - private IndexInput wrapIndexInput(String directory, String name, IndexInput in) { - return new SeekCountingIndexInput(in, directory, name); - } - - class RandomAccessSeekCountingIndexInput extends SeekCountingIndexInput implements RandomAccessInput { - - private final RandomAccessInput randomAccessInput; - - RandomAccessSeekCountingIndexInput(IndexInput in, String directory, String name) { - super(in, directory, name); - randomAccessInput = (RandomAccessInput) unwrap(in); - } - - @Override - public IndexInput clone() { - return new RandomAccessSeekCountingIndexInput(super.clone(), directory, name); - } - - @Override - public byte readByte(long pos) throws IOException { - return randomAccessInput.readByte(pos); - } - - @Override - public short readShort(long pos) throws IOException { - return randomAccessInput.readShort(pos); - } - - @Override - public int readInt(long pos) throws IOException { - return randomAccessInput.readInt(pos); - } - - @Override - public long readLong(long pos) throws IOException { - return randomAccessInput.readLong(pos); - } - } - - class SeekCountingIndexInput extends IndexInput { - - public static IndexInput unwrap(IndexInput input) { - while (input instanceof SeekCountingIndexInput) { - input = ((SeekCountingIndexInput) input).in; - } - return input; - } - - final IndexInput in; - final String directory; - final String name; - - SeekCountingIndexInput(IndexInput in, String directory, String name) { - super(unwrap(in).toString() + "[seek_tracked]"); - this.in = unwrap(in); - this.directory = directory; - this.name = name; - } - - @Override - public IndexInput clone() { - return new SeekCountingIndexInput(in.clone(), directory, name); - } - - @Override - public void close() throws IOException { - in.close(); - } - - @Override - public long getFilePointer() { - return in.getFilePointer(); - } - - @Override - public void seek(long pos) throws IOException { - in.seek(pos); - seekTracker.increment(directory, name); - } - - @Override - public long length() { - return in.length(); - } - - @Override - public IndexInput slice(String sliceDescription, long offset, long length) throws IOException { - return wrapIndexInput(directory, name, in.slice(sliceDescription + "[seek_tracked]", offset, length)); - } - - @Override - public RandomAccessInput randomAccessSlice(long offset, long length) throws IOException { - final IndexInput innerSlice = in.slice("randomaccess", offset, length); - if (innerSlice instanceof RandomAccessInput) { - // slice() already supports random access - return new RandomAccessSeekCountingIndexInput(innerSlice, directory, name); - } else { - IndexInput slice = wrapIndexInput(directory, name, innerSlice); - // return default impl - return new RandomAccessInput() { - @Override - public long length() { - return slice.length(); - } - - @Override - public byte readByte(long pos) throws IOException { - slice.seek(pos); - return slice.readByte(); - } - - @Override - public short readShort(long pos) throws IOException { - slice.seek(pos); - return slice.readShort(); - } - - @Override - public int readInt(long pos) throws IOException { - slice.seek(pos); - return slice.readInt(); - } - - @Override - public long readLong(long pos) throws IOException { - slice.seek(pos); - return slice.readLong(); - } - - @Override - public String toString() { - return "RandomAccessInput(" + slice + ")"; - } - }; - } - } - - @Override - public byte readByte() throws IOException { - return in.readByte(); - } - - @Override - public void readBytes(byte[] b, int offset, int len) throws IOException { - in.readBytes(b, offset, len); - } - - @Override - public void readBytes(byte[] b, int offset, int len, boolean useBuffer) throws IOException { - in.readBytes(b, offset, len, useBuffer); - } - - @Override - public short readShort() throws IOException { - return in.readShort(); - } - - @Override - public int readInt() throws IOException { - return in.readInt(); - } - - @Override - public int readVInt() throws IOException { - return in.readVInt(); - } - - @Override - public int readZInt() throws IOException { - return in.readZInt(); - } - - @Override - public long readLong() throws IOException { - return in.readLong(); - } - - @Override - public long readVLong() throws IOException { - return in.readVLong(); - } - - @Override - public long readZLong() throws IOException { - return in.readZLong(); - } - - @Override - public String readString() throws IOException { - return in.readString(); - } - - @Override - public Map readMapOfStrings() throws IOException { - return in.readMapOfStrings(); - } - - @Override - public Set readSetOfStrings() throws IOException { - return in.readSetOfStrings(); - } - - @Override - public void skipBytes(long numBytes) throws IOException { - in.skipBytes(numBytes); - } - - @Override - public void readFloats(float[] floats, int offset, int len) throws IOException { - in.readFloats(floats, offset, len); - } - - @Override - public void readLongs(long[] dst, int offset, int length) throws IOException { - in.readLongs(dst, offset, length); - } - - @Override - public void readInts(int[] dst, int offset, int length) throws IOException { - in.readInts(dst, offset, length); - } - - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/ShardSeekStats.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/ShardSeekStats.java deleted file mode 100644 index 1f904c0807fb..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/ShardSeekStats.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.xcontent.ToXContentObject; -import org.elasticsearch.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.Map; - -public record ShardSeekStats(String shard, Map seeksPerFile) implements Writeable, ToXContentObject { - - public ShardSeekStats(StreamInput in) throws IOException { - this(in.readString(), in.readMap(StreamInput::readLong)); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(this.shard); - out.writeMap(this.seeksPerFile, StreamOutput::writeLong); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - return builder.startObject().field("shard", this.shard).field("seeks", seeksPerFile).endObject(); - } -} diff --git a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/TransportSeekStatsAction.java b/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/TransportSeekStatsAction.java deleted file mode 100644 index bd1c35302b04..000000000000 --- a/test/external-modules/seek-tracking-directory/src/main/java/org/elasticsearch/test/seektracker/TransportSeekStatsAction.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -package org.elasticsearch.test.seektracker; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.nodes.TransportNodesAction; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.TransportService; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class TransportSeekStatsAction extends TransportNodesAction { - - private final SeekStatsService seekStatsService; - - @Inject - public TransportSeekStatsAction( - ThreadPool threadPool, - ClusterService clusterService, - TransportService transportService, - ActionFilters actionFilters, - SeekStatsService seekStatsService - ) { - super( - SeekTrackerPlugin.SEEK_STATS_ACTION.name(), - clusterService, - transportService, - actionFilters, - SeekStatsRequest::new, - threadPool.executor(ThreadPool.Names.MANAGEMENT) - ); - this.seekStatsService = seekStatsService; - } - - @Override - protected SeekStatsResponse newResponse(SeekStatsRequest request, List seekStats, List failures) { - return new SeekStatsResponse(clusterService.getClusterName(), seekStats, failures); - } - - @Override - protected SeekStatsRequest newNodeRequest(SeekStatsRequest request) { - // TODO don't wrap the whole top-level request, it contains heavy and irrelevant DiscoveryNode things; see #100878 - return request; - } - - @Override - protected NodeSeekStats newNodeResponse(StreamInput in, DiscoveryNode node) throws IOException { - return new NodeSeekStats(in); - } - - @Override - protected NodeSeekStats nodeOperation(SeekStatsRequest request, Task task) { - Map> seeks = new HashMap<>(); - if (request.getIndices().length == 0) { - for (Map.Entry entry : seekStatsService.getSeekStats().entrySet()) { - seeks.put(entry.getKey(), entry.getValue().getSeeks()); - } - } else { - for (String index : request.getIndices()) { - IndexSeekTracker indexSeekTracker = seekStatsService.getSeekStats(index); - if (indexSeekTracker != null) { - seeks.put(index, indexSeekTracker.getSeeks()); - } - } - } - return new NodeSeekStats(clusterService.localNode(), seeks); - } -} diff --git a/test/framework/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteUtils.java b/test/framework/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteUtils.java new file mode 100644 index 000000000000..5bfff80e3b86 --- /dev/null +++ b/test/framework/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteUtils.java @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.action.admin.cluster.reroute; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.support.ActionTestUtils; +import org.elasticsearch.action.support.SubscribableListener; +import org.elasticsearch.client.internal.ElasticsearchClient; +import org.elasticsearch.cluster.routing.allocation.command.AllocationCommand; + +import static org.elasticsearch.test.ESTestCase.TEST_REQUEST_TIMEOUT; +import static org.elasticsearch.test.ESTestCase.asInstanceOf; +import static org.elasticsearch.test.ESTestCase.safeAwait; +import static org.elasticsearch.test.ESTestCase.safeGet; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; + +/** + * Utilities for invoking {@link TransportClusterRerouteAction} in tests. + */ +public class ClusterRerouteUtils { + private ClusterRerouteUtils() {/* no instances */} + + /** + * Execute {@link TransportClusterRerouteAction} with the given (optional) sequence of {@link AllocationCommand} instances. Asserts that + * this succeeds. + */ + public static void reroute(ElasticsearchClient client, AllocationCommand... allocationCommands) { + doReroute(client, false, allocationCommands); + } + + /** + * Execute {@link TransportClusterRerouteAction} to reset the allocation failure counter. Asserts that this succeeds. + */ + public static void rerouteRetryFailed(ElasticsearchClient client) { + doReroute(client, true); + } + + private static void doReroute(ElasticsearchClient client, boolean retryFailed, AllocationCommand... allocationCommands) { + assertAcked( + safeGet( + client.execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).setRetryFailed(retryFailed) + .add(allocationCommands) + ) + ) + ); + } + + /** + * Execute {@link TransportClusterRerouteAction} with the given (optional) sequence of {@link AllocationCommand} instances, asserts that + * it fails, and returns the resulting (unwrapped) exception. + */ + public static Exception expectRerouteFailure(ElasticsearchClient client, AllocationCommand... allocationCommands) { + final Exception wrappedException = safeAwait( + SubscribableListener.newForked( + l -> client.execute( + TransportClusterRerouteAction.TYPE, + new ClusterRerouteRequest(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).add(allocationCommands), + ActionTestUtils.assertNoSuccessListener(l::onResponse) + ) + ) + ); + return asInstanceOf(Exception.class, wrappedException instanceof ElasticsearchException esx ? esx.unwrapCause() : wrappedException); + } +} diff --git a/test/framework/src/main/java/org/elasticsearch/test/hamcrest/ElasticsearchAssertions.java b/test/framework/src/main/java/org/elasticsearch/test/hamcrest/ElasticsearchAssertions.java index bf9eba87ee80..49c244167fe1 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/hamcrest/ElasticsearchAssertions.java +++ b/test/framework/src/main/java/org/elasticsearch/test/hamcrest/ElasticsearchAssertions.java @@ -71,7 +71,6 @@ import java.util.function.Consumer; import static org.apache.lucene.tests.util.LuceneTestCase.expectThrows; import static org.apache.lucene.tests.util.LuceneTestCase.expectThrowsAnyOf; -import static org.elasticsearch.test.ESIntegTestCase.client; import static org.elasticsearch.test.LambdaMatchers.transformedArrayItemsMatch; import static org.elasticsearch.test.LambdaMatchers.transformedItemsMatch; import static org.elasticsearch.test.LambdaMatchers.transformedMatch; @@ -181,10 +180,17 @@ public class ElasticsearchAssertions { * @param expectedBlockId the expected block id */ public static void assertBlocked(final RequestBuilder builder, @Nullable final Integer expectedBlockId) { - var e = ESTestCase.expectThrows(ClusterBlockException.class, builder); + assertBlocked(expectedBlockId, ESTestCase.expectThrows(ClusterBlockException.class, builder)); + } + + /** + * Checks that the given exception is a {@link ClusterBlockException}; if the given block ID is not {@code null} then the given + * exception must match that ID. + */ + public static void assertBlocked(@Nullable final Integer expectedBlockId, Exception exception) { + final var e = ESTestCase.asInstanceOf(ClusterBlockException.class, exception); assertThat(e.blocks(), not(empty())); - RestStatus status = checkRetryableBlock(e.blocks()) ? RestStatus.TOO_MANY_REQUESTS : RestStatus.FORBIDDEN; - assertThat(e.status(), equalTo(status)); + assertThat(e.status(), equalTo(checkRetryableBlock(e.blocks()) ? RestStatus.TOO_MANY_REQUESTS : RestStatus.FORBIDDEN)); if (expectedBlockId != null) { assertThat( diff --git a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java index 2d0e2295eb85..b046b5ca46e8 100644 --- a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java +++ b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java @@ -14,6 +14,7 @@ import org.elasticsearch.action.search.SearchResponse.Clusters; import org.elasticsearch.action.search.SearchResponseMerger; import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.util.concurrent.AtomicArray; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.core.Releasable; @@ -38,7 +39,6 @@ import static org.elasticsearch.xpack.core.async.AsyncTaskIndexService.restoreRe * run concurrently to 1 and ensures that we pause the search progress when an {@link AsyncSearchResponse} is built. */ class MutableSearchResponse implements Releasable { - private static final TotalHits EMPTY_TOTAL_HITS = new TotalHits(0L, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO); private final int totalShards; private final int skippedShards; private final Clusters clusters; @@ -95,7 +95,7 @@ class MutableSearchResponse implements Releasable { this.queryFailures = totalShards == -1 ? null : new AtomicArray<>(totalShards - skippedShards); this.isPartial = true; this.threadContext = threadContext; - this.totalHits = EMPTY_TOTAL_HITS; + this.totalHits = Lucene.TOTAL_HITS_GREATER_OR_EQUAL_TO_ZERO; this.localClusterComplete = false; } diff --git a/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/existence/FrozenExistenceDeciderIT.java b/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/existence/FrozenExistenceDeciderIT.java index 3e729e9139c2..154b5cb7f799 100644 --- a/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/existence/FrozenExistenceDeciderIT.java +++ b/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/existence/FrozenExistenceDeciderIT.java @@ -7,7 +7,7 @@ package org.elasticsearch.xpack.autoscaling.existence; -import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteRequest; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.blobcache.BlobCachePlugin; import org.elasticsearch.cluster.health.ClusterHealthStatus; @@ -141,7 +141,7 @@ public class FrozenExistenceDeciderIT extends AbstractFrozenAutoscalingIntegTest assertBusy(() -> { // cause a bit of cluster activity using an empty reroute call in case the `wait-for-index-colour` ILM step missed the // notification that partial-index is now GREEN. - client().admin().cluster().reroute(new ClusterRerouteRequest()).actionGet(); + ClusterRerouteUtils.reroute(client()); String[] indices = indices(); assertThat(indices, arrayContaining(PARTIAL_INDEX_NAME)); assertThat(indices, not(arrayContaining(INDEX_NAME))); diff --git a/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/storage/ReactiveStorageIT.java b/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/storage/ReactiveStorageIT.java index 9a171663e9df..25bd08afcad7 100644 --- a/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/storage/ReactiveStorageIT.java +++ b/x-pack/plugin/autoscaling/src/internalClusterTest/java/org/elasticsearch/xpack/autoscaling/storage/ReactiveStorageIT.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.autoscaling.storage; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.indices.shrink.ResizeType; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.index.IndexRequestBuilder; @@ -331,7 +332,7 @@ public class ReactiveStorageIT extends AutoscalingStorageIntegTestCase { long enoughSpaceForColocation = used + LOW_WATERMARK_BYTES; setTotalSpace(dataNode1Name, enoughSpaceForColocation); setTotalSpace(dataNode2Name, enoughSpaceForColocation); - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); waitForRelocation(); // Ensure that the relocated shard index files are removed from the data 2 node, @@ -385,10 +386,10 @@ public class ReactiveStorageIT extends AutoscalingStorageIntegTestCase { long tooLittleSpaceForShrink = requiredSpaceForShrink - Math.min(LOW_WATERMARK_BYTES - HIGH_WATERMARK_BYTES, used) - 1; assert tooLittleSpaceForShrink <= requiredSpaceForShrink; setTotalSpace(dataNode1Name, tooLittleSpaceForShrink); - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); assertThat(clusterAdmin().prepareHealth(shrinkName).get().getUnassignedShards(), equalTo(1)); setTotalSpace(dataNode1Name, tooLittleSpaceForShrink + 1); - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); ensureGreen(); indicesAdmin().prepareDelete(indexName).get(); @@ -495,10 +496,10 @@ public class ReactiveStorageIT extends AutoscalingStorageIntegTestCase { long tooLittleSpaceForClone = requiredSpaceForClone - Math.min(LOW_WATERMARK_BYTES - HIGH_WATERMARK_BYTES, used) - 1; assert tooLittleSpaceForClone <= requiredSpaceForClone; setTotalSpace(dataNode1Name, tooLittleSpaceForClone); - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); assertThat(clusterAdmin().prepareHealth(cloneName).get().getUnassignedShards(), equalTo(resizedShardCount)); setTotalSpace(dataNode1Name, requiredSpaceForClone); - assertAcked(clusterAdmin().prepareReroute()); + ClusterRerouteUtils.reroute(client()); ensureGreen(); indicesAdmin().prepareDelete(indexName).get(); diff --git a/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/ProgressListenableActionFuture.java b/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/ProgressListenableActionFuture.java index 6381f1c1e211..00cc9554a64e 100644 --- a/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/ProgressListenableActionFuture.java +++ b/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/ProgressListenableActionFuture.java @@ -7,12 +7,16 @@ package org.elasticsearch.blobcache.common; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.core.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.function.LongConsumer; import java.util.function.Supplier; /** @@ -24,29 +28,40 @@ import java.util.function.Supplier; */ class ProgressListenableActionFuture extends PlainActionFuture { + private static final Logger logger = LogManager.getLogger(ProgressListenableActionFuture.class); + private record PositionAndListener(long position, ActionListener listener) {} - protected final long start; - protected final long end; + final long start; + final long end; - // modified under 'this' mutex - private volatile List listeners; - protected volatile long progress; + /** + * A consumer that accepts progress made by this {@link ProgressListenableActionFuture}. The consumer is called before listeners are + * notified of the updated progress value in {@link #onProgress(long)} if the value is less than the actual end. The consumer can be + * called with out-of-order progress values. + */ + @Nullable + private final LongConsumer progressConsumer; + + private List listeners; + private long progress; private volatile boolean completed; /** * Creates a {@link ProgressListenableActionFuture} that accepts the progression * to be within {@code start} (inclusive) and {@code end} (exclusive) values. * - * @param start the start (inclusive) - * @param end the end (exclusive) + * @param start the start (inclusive) + * @param end the end (exclusive) + * @param progressConsumer a consumer that accepts the progress made by this {@link ProgressListenableActionFuture} */ - ProgressListenableActionFuture(long start, long end) { + ProgressListenableActionFuture(long start, long end, @Nullable LongConsumer progressConsumer) { super(); this.start = start; this.end = end; this.progress = start; this.completed = false; + this.progressConsumer = progressConsumer; assert invariant(); } @@ -108,6 +123,9 @@ class ProgressListenableActionFuture extends PlainActionFuture { } } if (listenersToExecute != null) { + if (progressConsumer != null) { + safeAcceptProgress(progressConsumer, progressValue); + } listenersToExecute.forEach(listener -> executeListener(listener, () -> progressValue)); } assert invariant(); @@ -115,8 +133,8 @@ class ProgressListenableActionFuture extends PlainActionFuture { @Override public void onResponse(Long result) { - if (result == null || result < start || end < result) { - assert false : start + " < " + result + " < " + end; + if (result == null || end != result) { + assert false : result + " != " + end; throw new IllegalArgumentException("Invalid completion value [start=" + start + ",end=" + end + ",response=" + result + ']'); } ensureNotCompleted(); @@ -143,6 +161,7 @@ class ProgressListenableActionFuture extends PlainActionFuture { synchronized (this) { assert completed == false; completed = true; + assert listeners == null || listeners.stream().allMatch(l -> progress < l.position() && l.position() <= end); listenersToExecute = this.listeners; listeners = null; } @@ -189,8 +208,18 @@ class ProgressListenableActionFuture extends PlainActionFuture { } } + private static void safeAcceptProgress(LongConsumer consumer, long progress) { + assert consumer != null; + try { + consumer.accept(progress); + } catch (Exception e) { + assert false : e; + logger.warn("Failed to consume progress value", e); + } + } + @Override - public String toString() { + public synchronized String toString() { return "ProgressListenableActionFuture[start=" + start + ", end=" diff --git a/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java b/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java index 6e6a11fbddc9..e3ff6a7ae4c7 100644 --- a/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java +++ b/x-pack/plugin/blob-cache/src/main/java/org/elasticsearch/blobcache/common/SparseFileTracker.java @@ -18,6 +18,7 @@ import java.util.Comparator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; +import java.util.function.LongConsumer; /** * Keeps track of the contents of a file that may not be completely present. @@ -199,7 +200,7 @@ public class SparseFileTracker { final Range newPendingRange = new Range( targetRange.start, range.end(), - new ProgressListenableActionFuture(targetRange.start, range.end()) + new ProgressListenableActionFuture(targetRange.start, range.end(), progressConsumer(targetRange.start)) ); ranges.add(newPendingRange); pendingRanges.add(newPendingRange); @@ -218,7 +219,7 @@ public class SparseFileTracker { final Range newPendingRange = new Range( targetRange.start, newPendingRangeEnd, - new ProgressListenableActionFuture(targetRange.start, newPendingRangeEnd) + new ProgressListenableActionFuture(targetRange.start, newPendingRangeEnd, progressConsumer(targetRange.start)) ); ranges.add(newPendingRange); pendingRanges.add(newPendingRange); @@ -260,6 +261,15 @@ public class SparseFileTracker { } } + private LongConsumer progressConsumer(long rangeStart) { + assert Thread.holdsLock(ranges); + if (rangeStart == complete) { + return this::updateCompletePointer; + } else { + return null; + } + } + public boolean checkAvailable(long upTo) { assert upTo <= length : "tried to check availability up to [" + upTo + "] but length is only [" + length + "]"; return complete >= upTo; @@ -464,11 +474,27 @@ public class SparseFileTracker { private void maybeUpdateCompletePointer(Range gapRange) { assert Thread.holdsLock(ranges); if (gapRange.start == 0) { - assert complete <= gapRange.end; - complete = gapRange.end; + updateCompletePointerHoldingLock(gapRange.end); } } + private void updateCompletePointerHoldingLock(long value) { + assert Thread.holdsLock(ranges); + assert complete <= value : complete + ">" + value; + complete = value; + } + + private void updateCompletePointer(long value) { + synchronized (ranges) { + updateCompletePointerHoldingLock(value); + } + } + + // used in tests + long getComplete() { + return complete; + } + private boolean assertGapRangePending(Range gapRange) { synchronized (ranges) { assert invariant(); @@ -535,9 +561,9 @@ public class SparseFileTracker { /** * Range in the file corresponding to the current gap */ - public final Range range; + private final Range range; - Gap(Range range) { + private Gap(Range range) { assert range.start < range.end : range.start + "-" + range.end; this.range = range; } diff --git a/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/ProgressListenableActionFutureTests.java b/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/ProgressListenableActionFutureTests.java index a94a3214fdd9..4490d087cec1 100644 --- a/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/ProgressListenableActionFutureTests.java +++ b/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/ProgressListenableActionFutureTests.java @@ -233,9 +233,49 @@ public class ProgressListenableActionFutureTests extends ESTestCase { assertThat(future.isDone(), is(true)); } + public void testLongConsumerCalledOnProgressUpdate() { + // min length of 2 to have at least one progress update before reaching the end + long length = randomLongBetween(2L, ByteSizeUnit.TB.toBytes(1L)); + long start = randomLongBetween(Long.MIN_VALUE, Long.MAX_VALUE - length); + long end = start + length; + + var consumed = new HashSet(); + var future = new ProgressListenableActionFuture( + start, + end, + p -> assertThat("LongConsumer should not consumed the same value twice", consumed.add(p), equalTo(true)) + ); + + long position = start; + int iters = randomIntBetween(10, 25); + for (int i = 0; i < iters && position < end - 1L; i++) { + var progress = randomLongBetween(position + 1L, end - 1L); + + var listener = new PlainActionFuture(); + future.addListener( + ActionListener.runBefore( + listener, + () -> assertThat( + "LongConsumer should have been called before listener completion", + consumed.contains(progress), + equalTo(true) + ) + ), + randomLongBetween(position + 1L, progress) + ); + future.onProgress(progress); + + assertThat(consumed.contains(progress), equalTo(true)); + assertThat(listener.isDone(), equalTo(true)); + position = progress; + } + future.onProgress(end); + assertThat("LongConsumer is not called when progress is updated to the end", consumed.contains(end), equalTo(false)); + } + private static ProgressListenableActionFuture randomFuture() { final long delta = randomLongBetween(1L, ByteSizeUnit.TB.toBytes(1L)); final long start = randomLongBetween(Long.MIN_VALUE, Long.MAX_VALUE - delta); - return new ProgressListenableActionFuture(start, start + delta); + return new ProgressListenableActionFuture(start, start + delta, null); } } diff --git a/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java b/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java index 5973b90c814d..fda560ccb2e2 100644 --- a/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java +++ b/x-pack/plugin/blob-cache/src/test/java/org/elasticsearch/blobcache/common/SparseFileTrackerTests.java @@ -517,6 +517,68 @@ public class SparseFileTrackerTests extends ESTestCase { assertThat(completedRanges, equalTo(expectedCompletedRanges)); } + public void testCompletePointerUpdatesOnProgress() { + // min length of 2 to have at least one progress update before reaching the end + byte[] bytes = new byte[between(2, 1024)]; + var tracker = new SparseFileTracker(getTestName(), bytes.length); + + long position = 0L; + for (int i = 0; i < 25 && position < tracker.getLength() - 1L; i++) { + var progress = randomLongBetween(position + 1L, tracker.getLength() - 1L); + + var listener = new PlainActionFuture(); + var gaps = tracker.waitForRange( + ByteRange.of(position, progress), + ByteRange.of(position, progress), + ActionListener.runBefore(listener, () -> assertThat(tracker.getComplete(), equalTo(progress))) + ); + assertThat(listener.isDone(), equalTo(false)); + assertThat(gaps, hasSize(1)); + + gaps.forEach(gap -> { + long latestUpdatedCompletePointer = gap.start(); + + for (long j = gap.start(); j < gap.end(); j++) { + final PlainActionFuture awaitingListener; + if (randomBoolean()) { + awaitingListener = new PlainActionFuture<>(); + var moreGaps = tracker.waitForRange( + ByteRange.of(gap.start(), j + 1L), + ByteRange.of(gap.start(), j + 1L), + awaitingListener + ); + assertThat(moreGaps.isEmpty(), equalTo(true)); + } else { + awaitingListener = null; + } + + assertThat(bytes[toIntBytes(j)], equalTo(UNAVAILABLE)); + bytes[toIntBytes(j)] = AVAILABLE; + gap.onProgress(j + 1L); + + if (awaitingListener != null && j < gap.end() - 1L) { + assertThat( + "Complete pointer should have been updated when a listener is waiting for the gap to be completed", + tracker.getComplete(), + equalTo(j + 1L) + ); + assertThat(awaitingListener.isDone(), equalTo(true)); + latestUpdatedCompletePointer = tracker.getComplete(); + } else { + assertThat( + "Complete pointer is not updated if no listeners are waiting for the gap to be completed", + tracker.getComplete(), + equalTo(latestUpdatedCompletePointer) + ); + } + } + gap.onCompletion(); + assertThat(tracker.getComplete(), equalTo(gap.end())); + }); + position = progress; + } + } + private static void checkRandomAbsentRange(byte[] fileContents, SparseFileTracker sparseFileTracker, boolean expectExact) { final long checkStart = randomLongBetween(0, fileContents.length - 1); final long checkEnd = randomLongBetween(checkStart, fileContents.length); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceDiagnosticsAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceDiagnosticsAction.java index 29edc88ecda7..00dcd5642401 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceDiagnosticsAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/action/GetInferenceDiagnosticsAction.java @@ -43,10 +43,6 @@ public class GetInferenceDiagnosticsAction extends ActionType { + + @UpdateForV9 // this constructor is unused in v9 public NodesDeprecationCheckRequest(StreamInput in) throws IOException { super(in); } @@ -24,6 +27,7 @@ public class NodesDeprecationCheckRequest extends BaseNodesRequest listener) { + public void updateConnectorError(String connectorId, String error, ActionListener listener) { try { - String connectorId = request.getConnectorId(); final UpdateRequest updateRequest = new UpdateRequest(CONNECTOR_INDEX_NAME, connectorId).doc( new IndexRequest(CONNECTOR_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) .id(connectorId) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) - .source(Map.of(Connector.ERROR_FIELD.getPreferredName(), request.getError())) + .source(new HashMap<>() { + { + put(Connector.ERROR_FIELD.getPreferredName(), error); + } + }) ); client.update(updateRequest, new DelegatingIndexNotFoundActionListener<>(connectorId, listener, (l, updateResponse) -> { if (updateResponse.getResult() == UpdateResponse.Result.NOT_FOUND) { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorErrorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorErrorAction.java index 7c279852625b..d71344e74aee 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorErrorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/TransportUpdateConnectorErrorAction.java @@ -41,6 +41,10 @@ public class TransportUpdateConnectorErrorAction extends HandledTransportAction< UpdateConnectorErrorAction.Request request, ActionListener listener ) { - connectorIndexService.updateConnectorError(request, listener.map(r -> new ConnectorUpdateActionResponse(r.getResult()))); + connectorIndexService.updateConnectorError( + request.getConnectorId(), + request.getError(), + listener.map(r -> new ConnectorUpdateActionResponse(r.getResult())) + ); } } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorErrorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorErrorAction.java index e6485285e199..ae86c1fc98df 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorErrorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/UpdateConnectorErrorAction.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.util.Objects; import static org.elasticsearch.action.ValidateActions.addValidationError; -import static org.elasticsearch.xcontent.ConstructingObjectParser.optionalConstructorArg; +import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg; public class UpdateConnectorErrorAction { @@ -81,7 +81,7 @@ public class UpdateConnectorErrorAction { ); static { - PARSER.declareStringOrNull(optionalConstructorArg(), Connector.ERROR_FIELD); + PARSER.declareStringOrNull(constructorArg(), Connector.ERROR_FIELD); } public static UpdateConnectorErrorAction.Request fromXContentBytes( diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java index 698c061d1bd6..a696c6e6dde5 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java @@ -725,6 +725,21 @@ public class ConnectorIndexServiceTests extends ESSingleNodeTestCase { assertThat(updateErrorRequest.getError(), equalTo(indexedConnector.getError())); } + public void testUpdateConnectorError_resetWithNull() throws Exception { + Connector connector = ConnectorTestUtils.getRandomConnector(); + String connectorId = randomUUID(); + ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); + assertThat(resp.status(), anyOf(equalTo(RestStatus.CREATED), equalTo(RestStatus.OK))); + + UpdateConnectorErrorAction.Request updateErrorRequest = new UpdateConnectorErrorAction.Request(connectorId, null); + + DocWriteResponse updateResponse = awaitUpdateConnectorError(updateErrorRequest); + assertThat(updateResponse.status(), equalTo(RestStatus.OK)); + + Connector indexedConnector = awaitGetConnector(connectorId); + assertThat(updateErrorRequest.getError(), equalTo(indexedConnector.getError())); + } + public void testUpdateConnectorNameOrDescription() throws Exception { Connector connector = ConnectorTestUtils.getRandomConnector(); String connectorId = randomUUID(); @@ -1336,7 +1351,7 @@ public class ConnectorIndexServiceTests extends ESSingleNodeTestCase { CountDownLatch latch = new CountDownLatch(1); final AtomicReference resp = new AtomicReference<>(null); final AtomicReference exc = new AtomicReference<>(null); - connectorIndexService.updateConnectorError(updatedError, new ActionListener<>() { + connectorIndexService.updateConnectorError(updatedError.getConnectorId(), updatedError.getError(), new ActionListener<>() { @Override public void onResponse(UpdateResponse indexResponse) { resp.set(indexResponse); diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Expression.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Expression.java index 00765a8c0528..ee7e0aa81f81 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Expression.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Expression.java @@ -6,6 +6,8 @@ */ package org.elasticsearch.xpack.esql.core.expression; +import org.elasticsearch.common.io.stream.NamedWriteable; +import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.capabilities.Resolvable; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; @@ -14,6 +16,7 @@ import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.core.util.StringUtils; +import java.io.IOException; import java.util.List; import java.util.function.Supplier; @@ -26,7 +29,7 @@ import java.util.function.Supplier; * a, b, ABS(c), and i are all Expressions, with ABS(c) being a Function * (which is a type of expression) with a single child, c. */ -public abstract class Expression extends Node implements Resolvable { +public abstract class Expression extends Node implements Resolvable, NamedWriteable { public static class TypeResolution { private final boolean failed; @@ -78,6 +81,18 @@ public abstract class Expression extends Node implements Resolvable super(source, children); } + @Override + public void writeTo(StreamOutput out) throws IOException { + // TODO remove this function entirely once all subclasses implement it + throw new UnsupportedOperationException("todo unsupported"); + } + + @Override + public String getWriteableName() { + // TODO remove this function entirely once all subclasses implement it + throw new UnsupportedOperationException("todo unsupported"); + } + // whether the expression can be evaluated statically (folded) or not public boolean foldable() { return false; diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/util/StringUtils.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/util/StringUtils.java index 1eb7e1cce5cb..47246a4e190d 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/util/StringUtils.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/util/StringUtils.java @@ -392,4 +392,26 @@ public final class StringUtils { public static boolean isQualified(String indexWildcard) { return indexWildcard.indexOf(REMOTE_CLUSTER_INDEX_SEPARATOR) > 0; } + + public static boolean isInteger(String value) { + for (char c : value.trim().toCharArray()) { + if (Character.isDigit(c) == false) { + return false; + } + } + return true; + } + + public static boolean isValidParamName(String value) { + // A valid name starts with a letter and contain only letter, digit or _ + if (Character.isLetter(value.charAt(0)) == false) { + return false; + } + for (char c : value.trim().toCharArray()) { + if (Character.isLetterOrDigit(c) == false && c != '_') { + return false; + } + } + return true; + } } diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/TimeSeriesSortedSourceOperatorFactory.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/TimeSeriesSortedSourceOperatorFactory.java index 8b52aa84aef2..3dde3ba75be7 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/TimeSeriesSortedSourceOperatorFactory.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/TimeSeriesSortedSourceOperatorFactory.java @@ -275,8 +275,8 @@ public class TimeSeriesSortedSourceOperatorFactory extends LuceneOperator.Factor void consume() throws IOException { if (queue != null) { - currentTsid = BytesRef.deepCopyOf(queue.top().timeSeriesHash); if (queue.size() > 0) { + currentTsid = BytesRef.deepCopyOf(queue.top().timeSeriesHash); queue.top().reinitializeIfNeeded(Thread.currentThread()); } while (queue.size() > 0) { diff --git a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java index 7c57212d0f57..bf54dcbfa96f 100644 --- a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java +++ b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java @@ -256,6 +256,23 @@ public class RestEsqlIT extends RestEsqlTestCase { assertThat(deleteIndex("index2").isAcknowledged(), Matchers.is(true)); } + public void testTableDuplicateNames() throws IOException { + Request request = new Request("POST", "/_query"); + request.setJsonEntity(""" + { + "query": "FROM a=1", + "tables": { + "t": { + "a": {"integer": [1]}, + "a": {"integer": [1]} + } + } + }"""); + ResponseException re = expectThrows(ResponseException.class, () -> client().performRequest(request)); + assertThat(re.getResponse().getStatusLine().getStatusCode(), equalTo(400)); + assertThat(re.getMessage(), containsString("[6:10] Duplicate field 'a'")); + } + private void assertException(String query, String... errorMessages) throws IOException { ResponseException re = expectThrows(ResponseException.class, () -> runEsqlSync(requestObjectBuilder().query(query))); assertThat(re.getResponse().getStatusLine().getStatusCode(), equalTo(400)); diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java index a42f02a22aba..3e7b1e927a9b 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java @@ -321,43 +321,52 @@ public abstract class EsqlSpecTestCase extends ESRestTestCase { * "tables" parameter sent if there is a LOOKUP in the request. If you * add to this, you must also add to {@link EsqlTestUtils#tables}; */ - private Map>> tables() { - Map>> tables = new TreeMap<>(); + private Map> tables() { + Map> tables = new TreeMap<>(); tables.put( "int_number_names", EsqlTestUtils.table( - Map.entry("int:integer", IntStream.range(0, 10).boxed().toList()), - Map.entry("name:keyword", IntStream.range(0, 10).mapToObj(EsqlTestUtils::numberName).toList()) + Map.entry("int", new RestEsqlTestCase.TypeAndValues("integer", IntStream.range(0, 10).boxed().toList())), + Map.entry( + "name", + new RestEsqlTestCase.TypeAndValues("keyword", IntStream.range(0, 10).mapToObj(EsqlTestUtils::numberName).toList()) + ) ) ); tables.put( "long_number_names", EsqlTestUtils.table( - Map.entry("long:long", LongStream.range(0, 10).boxed().toList()), - Map.entry("name:keyword", IntStream.range(0, 10).mapToObj(EsqlTestUtils::numberName).toList()) + Map.entry("long", new RestEsqlTestCase.TypeAndValues("long", LongStream.range(0, 10).boxed().toList())), + Map.entry( + "name", + new RestEsqlTestCase.TypeAndValues("keyword", IntStream.range(0, 10).mapToObj(EsqlTestUtils::numberName).toList()) + ) ) ); tables.put( "double_number_names", EsqlTestUtils.table( - Map.entry("double:double", List.of(2.03, 2.08)), - Map.entry("name:keyword", List.of("two point zero three", "two point zero eight")) + Map.entry("double", new RestEsqlTestCase.TypeAndValues("double", List.of(2.03, 2.08))), + Map.entry("name", new RestEsqlTestCase.TypeAndValues("keyword", List.of("two point zero three", "two point zero eight"))) ) ); tables.put( "double_number_names_with_null", EsqlTestUtils.table( - Map.entry("double:double", List.of(2.03, 2.08, 0.0)), - Map.entry("name:keyword", Arrays.asList("two point zero three", "two point zero eight", null)) + Map.entry("double", new RestEsqlTestCase.TypeAndValues("double", List.of(2.03, 2.08, 0.0))), + Map.entry( + "name", + new RestEsqlTestCase.TypeAndValues("keyword", Arrays.asList("two point zero three", "two point zero eight", null)) + ) ) ); tables.put( "big", EsqlTestUtils.table( - Map.entry("aa:keyword", List.of("foo", "bar", "baz", "foo")), - Map.entry("ab:keyword", List.of("zoo", "zop", "zoi", "foo")), - Map.entry("na:integer", List.of(1, 10, 100, 2)), - Map.entry("nb:integer", List.of(-1, -10, -100, -2)) + Map.entry("aa", new RestEsqlTestCase.TypeAndValues("keyword", List.of("foo", "bar", "baz", "foo"))), + Map.entry("ab", new RestEsqlTestCase.TypeAndValues("keyword", List.of("zoo", "zop", "zoi", "foo"))), + Map.entry("na", new RestEsqlTestCase.TypeAndValues("integer", List.of(1, 10, 100, 2))), + Map.entry("nb", new RestEsqlTestCase.TypeAndValues("integer", List.of(-1, -10, -100, -2))) ) ); return tables; diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java index 349f9445030c..a672e4a50612 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java @@ -109,11 +109,13 @@ public abstract class RestEsqlTestCase extends ESRestTestCase { this.mode = mode; } + public record TypeAndValues(String type, List values) {} + public static class RequestObjectBuilder { private final XContentBuilder builder; private boolean isBuilt = false; - private Map>> tables; + private Map> tables; private Boolean keepOnCompletion = null; @@ -131,7 +133,7 @@ public abstract class RestEsqlTestCase extends ESRestTestCase { return this; } - public RequestObjectBuilder tables(Map>> tables) { + public RequestObjectBuilder tables(Map> tables) { this.tables = tables; return this; } @@ -181,7 +183,17 @@ public abstract class RestEsqlTestCase extends ESRestTestCase { public RequestObjectBuilder build() throws IOException { if (isBuilt == false) { if (tables != null) { - builder.field("tables", tables); + builder.startObject("tables"); + for (var table : tables.entrySet()) { + builder.startObject(table.getKey()); + for (var column : table.getValue().entrySet()) { + builder.startObject(column.getKey()); + builder.field(column.getValue().type(), column.getValue().values()); + builder.endObject(); + } + builder.endObject(); + } + builder.endObject(); } builder.endObject(); isBuilt = true; @@ -473,36 +485,39 @@ public abstract class RestEsqlTestCase extends ESRestTestCase { public void testErrorMessageForInvalidParams() throws IOException { ResponseException re = expectThrows( ResponseException.class, - () -> runEsql(requestObjectBuilder().query("row a = 1").params("[{\"x\":\"y\"}]")) + () -> runEsqlSync( + requestObjectBuilder().query("row a = 1 | eval x = ?, y = ?") + .params( + "[{\"1\": \"v1\"}, {\"1-\": \"v1\"}, {\"_a\": \"v1\"}, {\"@-#\": \"v1\"}, true, 123, " + + "{\"type\": \"byte\", \"value\": 5}]" + ) + ) ); - assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("Required [value, type]")); - } - - public void testErrorMessageForMissingTypeInParams() throws IOException { - ResponseException re = expectThrows( + String error = EntityUtils.toString(re.getResponse().getEntity()).replaceAll("\\\\\n\s+\\\\", ""); + assertThat(error, containsString("[1] is not a valid parameter name")); + assertThat(error, containsString("[1-] is not a valid parameter name")); + assertThat(error, containsString("[_a] is not a valid parameter name")); + assertThat(error, containsString("[@-#] is not a valid parameter name")); + assertThat(error, containsString("Params cannot contain both named and unnamed parameters")); + assertThat(error, containsString("Cannot parse more than one key:value pair as parameter")); + re = expectThrows( ResponseException.class, - () -> runEsql(requestObjectBuilder().query("row a = 1").params("[\"x\", 123, true, {\"value\": \"y\"}]")) - ); - assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("Required [type]")); - } - - public void testErrorMessageForMissingValueInParams() throws IOException { - ResponseException re = expectThrows( - ResponseException.class, - () -> runEsql(requestObjectBuilder().query("row a = 1").params("[\"x\", 123, true, {\"type\": \"y\"}]")) - ); - assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("Required [value]")); - } - - public void testErrorMessageForInvalidTypeInParams() throws IOException { - ResponseException re = expectThrows( - ResponseException.class, - () -> runEsqlSync(requestObjectBuilder().query("row a = 1 | eval x = ?").params("[{\"type\": \"byte\", \"value\": 5}]")) + () -> runEsqlSync(requestObjectBuilder().query("row a = ?0, b= ?2").params("[{\"n1\": \"v1\"}]")) ); assertThat( EntityUtils.toString(re.getResponse().getEntity()), - containsString("EVAL does not support type [byte] in expression [?]") + containsString("No parameter is defined for position 0, did you mean position 1") ); + assertThat( + EntityUtils.toString(re.getResponse().getEntity()), + containsString("No parameter is defined for position 2, did you mean position 1") + ); + + re = expectThrows( + ResponseException.class, + () -> runEsqlSync(requestObjectBuilder().query("row a = ?n0").params("[{\"n1\": \"v1\"}]")) + ); + assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("Unknown query parameter [n0], did you mean [n1]")); } public void testErrorMessageForLiteralDateMathOverflow() throws IOException { @@ -547,12 +562,9 @@ public abstract class RestEsqlTestCase extends ESRestTestCase { public void testErrorMessageForArrayValuesInParams() throws IOException { ResponseException re = expectThrows( ResponseException.class, - () -> runEsql(requestObjectBuilder().query("row a = 1 | eval x = ?").params("[{\"type\": \"integer\", \"value\": [5, 6, 7]}]")) - ); - assertThat( - EntityUtils.toString(re.getResponse().getEntity()), - containsString("[params] value doesn't support values of type: START_ARRAY") + () -> runEsql(requestObjectBuilder().query("row a = 1 | eval x = ?").params("[{\"n1\": [5, 6, 7]}]")) ); + assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("n1=[5, 6, 7] is not supported as a parameter")); } private static String expectedTextBody(String format, int count, @Nullable Character csvDelimiter) { diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/EsqlDisruptionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/EsqlDisruptionIT.java index e005e2143522..df1b2c9f00f4 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/EsqlDisruptionIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/EsqlDisruptionIT.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.esql.action; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.admin.cluster.node.tasks.list.TransportListTasksAction; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.cluster.coordination.Coordinator; import org.elasticsearch.cluster.coordination.FollowersChecker; import org.elasticsearch.cluster.coordination.LeaderChecker; @@ -29,7 +30,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; @ESIntegTestCase.ClusterScope(scope = TEST, minNumDataNodes = 2, maxNumDataNodes = 4) public class EsqlDisruptionIT extends EsqlActionIT { @@ -140,7 +140,7 @@ public class EsqlDisruptionIT extends EsqlActionIT { try { internalCluster().clearDisruptionScheme(false); ensureFullyConnectedCluster(); - assertBusy(() -> assertAcked(clusterAdmin().prepareReroute().setRetryFailed(true)), 1, TimeUnit.MINUTES); + assertBusy(() -> ClusterRerouteUtils.rerouteRetryFailed(client()), 1, TimeUnit.MINUTES); ensureYellow(); } catch (Exception e) { throw new AssertionError(e); diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 index fb424b16ac40..61ce9bd9152e 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 @@ -156,6 +156,11 @@ ASTERISK : '*'; SLASH : '/'; PERCENT : '%'; +NAMED_OR_POSITIONAL_PARAM + : PARAM LETTER UNQUOTED_ID_BODY* + | PARAM DIGIT+ + ; + // Brackets are funny. We can happen upon a CLOSING_BRACKET in two ways - one // way is to start in an explain command which then shifts us to expression // mode. Thus, the two popModes on CLOSING_BRACKET. The other way could as diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens index 30ce0d5eea55..04798fc3dca8 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens @@ -65,62 +65,63 @@ MINUS=64 ASTERISK=65 SLASH=66 PERCENT=67 -OPENING_BRACKET=68 -CLOSING_BRACKET=69 -UNQUOTED_IDENTIFIER=70 -QUOTED_IDENTIFIER=71 -EXPR_LINE_COMMENT=72 -EXPR_MULTILINE_COMMENT=73 -EXPR_WS=74 -METADATA=75 -FROM_LINE_COMMENT=76 -FROM_MULTILINE_COMMENT=77 -FROM_WS=78 -ID_PATTERN=79 -PROJECT_LINE_COMMENT=80 -PROJECT_MULTILINE_COMMENT=81 -PROJECT_WS=82 -AS=83 -RENAME_LINE_COMMENT=84 -RENAME_MULTILINE_COMMENT=85 -RENAME_WS=86 -ON=87 -WITH=88 -ENRICH_POLICY_NAME=89 -ENRICH_LINE_COMMENT=90 -ENRICH_MULTILINE_COMMENT=91 -ENRICH_WS=92 -ENRICH_FIELD_LINE_COMMENT=93 -ENRICH_FIELD_MULTILINE_COMMENT=94 -ENRICH_FIELD_WS=95 -LOOKUP_LINE_COMMENT=96 -LOOKUP_MULTILINE_COMMENT=97 -LOOKUP_WS=98 -LOOKUP_FIELD_LINE_COMMENT=99 -LOOKUP_FIELD_MULTILINE_COMMENT=100 -LOOKUP_FIELD_WS=101 -MVEXPAND_LINE_COMMENT=102 -MVEXPAND_MULTILINE_COMMENT=103 -MVEXPAND_WS=104 -INFO=105 -SHOW_LINE_COMMENT=106 -SHOW_MULTILINE_COMMENT=107 -SHOW_WS=108 -FUNCTIONS=109 -META_LINE_COMMENT=110 -META_MULTILINE_COMMENT=111 -META_WS=112 -COLON=113 -SETTING=114 -SETTING_LINE_COMMENT=115 -SETTTING_MULTILINE_COMMENT=116 -SETTING_WS=117 -METRICS_LINE_COMMENT=118 -METRICS_MULTILINE_COMMENT=119 -METRICS_WS=120 -CLOSING_METRICS_LINE_COMMENT=121 -CLOSING_METRICS_MULTILINE_COMMENT=122 -CLOSING_METRICS_WS=123 +NAMED_OR_POSITIONAL_PARAM=68 +OPENING_BRACKET=69 +CLOSING_BRACKET=70 +UNQUOTED_IDENTIFIER=71 +QUOTED_IDENTIFIER=72 +EXPR_LINE_COMMENT=73 +EXPR_MULTILINE_COMMENT=74 +EXPR_WS=75 +METADATA=76 +FROM_LINE_COMMENT=77 +FROM_MULTILINE_COMMENT=78 +FROM_WS=79 +ID_PATTERN=80 +PROJECT_LINE_COMMENT=81 +PROJECT_MULTILINE_COMMENT=82 +PROJECT_WS=83 +AS=84 +RENAME_LINE_COMMENT=85 +RENAME_MULTILINE_COMMENT=86 +RENAME_WS=87 +ON=88 +WITH=89 +ENRICH_POLICY_NAME=90 +ENRICH_LINE_COMMENT=91 +ENRICH_MULTILINE_COMMENT=92 +ENRICH_WS=93 +ENRICH_FIELD_LINE_COMMENT=94 +ENRICH_FIELD_MULTILINE_COMMENT=95 +ENRICH_FIELD_WS=96 +LOOKUP_LINE_COMMENT=97 +LOOKUP_MULTILINE_COMMENT=98 +LOOKUP_WS=99 +LOOKUP_FIELD_LINE_COMMENT=100 +LOOKUP_FIELD_MULTILINE_COMMENT=101 +LOOKUP_FIELD_WS=102 +MVEXPAND_LINE_COMMENT=103 +MVEXPAND_MULTILINE_COMMENT=104 +MVEXPAND_WS=105 +INFO=106 +SHOW_LINE_COMMENT=107 +SHOW_MULTILINE_COMMENT=108 +SHOW_WS=109 +FUNCTIONS=110 +META_LINE_COMMENT=111 +META_MULTILINE_COMMENT=112 +META_WS=113 +COLON=114 +SETTING=115 +SETTING_LINE_COMMENT=116 +SETTTING_MULTILINE_COMMENT=117 +SETTING_WS=118 +METRICS_LINE_COMMENT=119 +METRICS_MULTILINE_COMMENT=120 +METRICS_WS=121 +CLOSING_METRICS_LINE_COMMENT=122 +CLOSING_METRICS_MULTILINE_COMMENT=123 +CLOSING_METRICS_WS=124 'dissect'=1 'drop'=2 'enrich'=3 @@ -177,11 +178,11 @@ CLOSING_METRICS_WS=123 '*'=65 '/'=66 '%'=67 -']'=69 -'metadata'=75 -'as'=83 -'on'=87 -'with'=88 -'info'=105 -'functions'=109 -':'=113 +']'=70 +'metadata'=76 +'as'=84 +'on'=88 +'with'=89 +'info'=106 +'functions'=110 +':'=114 diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 index 29892d464c0e..69d65ea9a214 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 @@ -170,13 +170,18 @@ constant | decimalValue #decimalLiteral | integerValue #integerLiteral | booleanValue #booleanLiteral - | PARAM #inputParam + | params #inputParams | string #stringLiteral | OPENING_BRACKET numericValue (COMMA numericValue)* CLOSING_BRACKET #numericArrayLiteral | OPENING_BRACKET booleanValue (COMMA booleanValue)* CLOSING_BRACKET #booleanArrayLiteral | OPENING_BRACKET string (COMMA string)* CLOSING_BRACKET #stringArrayLiteral ; +params + : PARAM #inputParam + | NAMED_OR_POSITIONAL_PARAM #inputNamedOrPositionalParam + ; + limitCommand : LIMIT INTEGER_LITERAL ; diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens index 30ce0d5eea55..04798fc3dca8 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens @@ -65,62 +65,63 @@ MINUS=64 ASTERISK=65 SLASH=66 PERCENT=67 -OPENING_BRACKET=68 -CLOSING_BRACKET=69 -UNQUOTED_IDENTIFIER=70 -QUOTED_IDENTIFIER=71 -EXPR_LINE_COMMENT=72 -EXPR_MULTILINE_COMMENT=73 -EXPR_WS=74 -METADATA=75 -FROM_LINE_COMMENT=76 -FROM_MULTILINE_COMMENT=77 -FROM_WS=78 -ID_PATTERN=79 -PROJECT_LINE_COMMENT=80 -PROJECT_MULTILINE_COMMENT=81 -PROJECT_WS=82 -AS=83 -RENAME_LINE_COMMENT=84 -RENAME_MULTILINE_COMMENT=85 -RENAME_WS=86 -ON=87 -WITH=88 -ENRICH_POLICY_NAME=89 -ENRICH_LINE_COMMENT=90 -ENRICH_MULTILINE_COMMENT=91 -ENRICH_WS=92 -ENRICH_FIELD_LINE_COMMENT=93 -ENRICH_FIELD_MULTILINE_COMMENT=94 -ENRICH_FIELD_WS=95 -LOOKUP_LINE_COMMENT=96 -LOOKUP_MULTILINE_COMMENT=97 -LOOKUP_WS=98 -LOOKUP_FIELD_LINE_COMMENT=99 -LOOKUP_FIELD_MULTILINE_COMMENT=100 -LOOKUP_FIELD_WS=101 -MVEXPAND_LINE_COMMENT=102 -MVEXPAND_MULTILINE_COMMENT=103 -MVEXPAND_WS=104 -INFO=105 -SHOW_LINE_COMMENT=106 -SHOW_MULTILINE_COMMENT=107 -SHOW_WS=108 -FUNCTIONS=109 -META_LINE_COMMENT=110 -META_MULTILINE_COMMENT=111 -META_WS=112 -COLON=113 -SETTING=114 -SETTING_LINE_COMMENT=115 -SETTTING_MULTILINE_COMMENT=116 -SETTING_WS=117 -METRICS_LINE_COMMENT=118 -METRICS_MULTILINE_COMMENT=119 -METRICS_WS=120 -CLOSING_METRICS_LINE_COMMENT=121 -CLOSING_METRICS_MULTILINE_COMMENT=122 -CLOSING_METRICS_WS=123 +NAMED_OR_POSITIONAL_PARAM=68 +OPENING_BRACKET=69 +CLOSING_BRACKET=70 +UNQUOTED_IDENTIFIER=71 +QUOTED_IDENTIFIER=72 +EXPR_LINE_COMMENT=73 +EXPR_MULTILINE_COMMENT=74 +EXPR_WS=75 +METADATA=76 +FROM_LINE_COMMENT=77 +FROM_MULTILINE_COMMENT=78 +FROM_WS=79 +ID_PATTERN=80 +PROJECT_LINE_COMMENT=81 +PROJECT_MULTILINE_COMMENT=82 +PROJECT_WS=83 +AS=84 +RENAME_LINE_COMMENT=85 +RENAME_MULTILINE_COMMENT=86 +RENAME_WS=87 +ON=88 +WITH=89 +ENRICH_POLICY_NAME=90 +ENRICH_LINE_COMMENT=91 +ENRICH_MULTILINE_COMMENT=92 +ENRICH_WS=93 +ENRICH_FIELD_LINE_COMMENT=94 +ENRICH_FIELD_MULTILINE_COMMENT=95 +ENRICH_FIELD_WS=96 +LOOKUP_LINE_COMMENT=97 +LOOKUP_MULTILINE_COMMENT=98 +LOOKUP_WS=99 +LOOKUP_FIELD_LINE_COMMENT=100 +LOOKUP_FIELD_MULTILINE_COMMENT=101 +LOOKUP_FIELD_WS=102 +MVEXPAND_LINE_COMMENT=103 +MVEXPAND_MULTILINE_COMMENT=104 +MVEXPAND_WS=105 +INFO=106 +SHOW_LINE_COMMENT=107 +SHOW_MULTILINE_COMMENT=108 +SHOW_WS=109 +FUNCTIONS=110 +META_LINE_COMMENT=111 +META_MULTILINE_COMMENT=112 +META_WS=113 +COLON=114 +SETTING=115 +SETTING_LINE_COMMENT=116 +SETTTING_MULTILINE_COMMENT=117 +SETTING_WS=118 +METRICS_LINE_COMMENT=119 +METRICS_MULTILINE_COMMENT=120 +METRICS_WS=121 +CLOSING_METRICS_LINE_COMMENT=122 +CLOSING_METRICS_MULTILINE_COMMENT=123 +CLOSING_METRICS_WS=124 'dissect'=1 'drop'=2 'enrich'=3 @@ -177,11 +178,11 @@ CLOSING_METRICS_WS=123 '*'=65 '/'=66 '%'=67 -']'=69 -'metadata'=75 -'as'=83 -'on'=87 -'with'=88 -'info'=105 -'functions'=109 -':'=113 +']'=70 +'metadata'=76 +'as'=84 +'on'=88 +'with'=89 +'info'=106 +'functions'=110 +':'=114 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 75600e64e3e9..3eef9f7356b3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -57,18 +57,28 @@ public class EsqlCapabilities { */ private static final String LOOKUP_COMMAND = "lookup_command"; + /** + * Support for the syntax {@code "tables": {"type": []}}. + */ + private static final String TABLES_TYPES = "tables_types"; + /** * Support for requesting the "REPEAT" command. */ private static final String REPEAT = "repeat"; - public static final Set CAPABILITIES = capabilities(); - /** * Cast string literals to datetime in addition and subtraction when the other side is a date or time interval. */ public static final String STRING_LITERAL_AUTO_CASTING_TO_DATETIME_ADD_SUB = "string_literal_auto_casting_to_datetime_add_sub"; + /** + * Support for named or positional parameters in EsqlQueryRequest. + */ + private static final String NAMED_POSITIONAL_PARAMETER = "named_positional_parameter"; + + public static final Set CAPABILITIES = capabilities(); + private static Set capabilities() { List caps = new ArrayList<>(); caps.add(FN_CBRT); @@ -78,6 +88,7 @@ public class EsqlCapabilities { caps.add(METADATA_IGNORED_FIELD); caps.add(FN_MV_APPEND); caps.add(REPEAT); + caps.add(NAMED_POSITIONAL_PARAMETER); if (Build.current().isSnapshot()) { caps.add(LOOKUP_COMMAND); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java index 542b220d398d..e81c9919fe0a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java @@ -21,12 +21,11 @@ import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; import org.elasticsearch.xpack.esql.Column; -import org.elasticsearch.xpack.esql.parser.TypedParamValue; +import org.elasticsearch.xpack.esql.parser.QueryParams; import org.elasticsearch.xpack.esql.plugin.QueryPragmas; import java.io.IOException; import java.util.Iterator; -import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TreeMap; @@ -46,7 +45,7 @@ public class EsqlQueryRequest extends org.elasticsearch.xpack.core.esql.action.E private Locale locale; private QueryBuilder filter; private QueryPragmas pragmas = new QueryPragmas(Settings.EMPTY); - private List params = List.of(); + private QueryParams params = QueryParams.EMPTY; private TimeValue waitForCompletionTimeout = DEFAULT_WAIT_FOR_COMPLETION; private TimeValue keepAlive = DEFAULT_KEEP_ALIVE; private boolean keepOnCompletion; @@ -159,11 +158,11 @@ public class EsqlQueryRequest extends org.elasticsearch.xpack.core.esql.action.E return pragmas; } - public List params() { + public QueryParams params() { return params; } - public void params(List params) { + public void params(QueryParams params) { this.params = params; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ParseTables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ParseTables.java index 97728196a0ce..cc56285f3c78 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ParseTables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ParseTables.java @@ -83,17 +83,11 @@ public class ParseTables { return columns; } case FIELD_NAME -> { - String[] fname = p.currentName().split(":"); - if (fname.length != 2) { - throw new XContentParseException( - p.getTokenLocation(), - "expected columns named name:type but was [" + p.currentName() + "]" - ); + String name = p.currentName(); + if (columns.containsKey(name)) { + throw new XContentParseException(p.getTokenLocation(), "duplicate column name [" + name + "]"); } - if (columns.containsKey(fname[0])) { - throw new XContentParseException(p.getTokenLocation(), "duplicate column name [" + fname[0] + "]"); - } - columns.put(fname[0], parseColumn(fname[1])); + columns.put(name, parseColumn()); } default -> throw new XContentParseException( p.getTokenLocation(), @@ -108,14 +102,26 @@ public class ParseTables { } } - private Column parseColumn(String type) throws IOException { - return switch (type) { + private Column parseColumn() throws IOException { + if (p.nextToken() != XContentParser.Token.START_OBJECT) { + throw new XContentParseException(p.getTokenLocation(), "expected " + XContentParser.Token.START_OBJECT); + } + if (p.nextToken() != XContentParser.Token.FIELD_NAME) { + throw new XContentParseException(p.getTokenLocation(), "expected " + XContentParser.Token.FIELD_NAME); + } + String type = p.currentName(); + Column result = switch (type) { case "integer" -> parseIntColumn(); case "keyword" -> parseKeywordColumn(); case "long" -> parseLongColumn(); case "double" -> parseDoubleColumn(); default -> throw new XContentParseException(p.getTokenLocation(), "unsupported type [" + type + "]"); }; + if (p.nextToken() != XContentParser.Token.END_OBJECT) { + result.close(); + throw new XContentParseException(p.getTokenLocation(), "expected " + XContentParser.Token.END_OBJECT); + } + return result; } private Column parseKeywordColumn() throws IOException { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java index 793f453d5ebf..2c6b5e7a6b49 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java @@ -10,42 +10,59 @@ package org.elasticsearch.xpack.esql.action; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.query.AbstractQueryBuilder; -import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ObjectParser; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.XContentLocation; import org.elasticsearch.xcontent.XContentParseException; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.esql.parser.ContentLocation; -import org.elasticsearch.xpack.esql.parser.TypedParamValue; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.parser.QueryParam; +import org.elasticsearch.xpack.esql.parser.QueryParams; import org.elasticsearch.xpack.esql.plugin.QueryPragmas; +import org.elasticsearch.xpack.esql.type.EsqlDataTypes; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.function.Supplier; -import static org.elasticsearch.common.xcontent.XContentParserUtils.parseFieldsValue; -import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg; -import static org.elasticsearch.xcontent.ObjectParser.ValueType.VALUE_ARRAY; +import static org.elasticsearch.xcontent.ObjectParser.ValueType.VALUE_OBJECT_ARRAY; +import static org.elasticsearch.xpack.esql.core.util.StringUtils.isValidParamName; /** Static methods for parsing xcontent requests to transport requests. */ final class RequestXContent { - private static final ConstructingObjectParser PARAM_PARSER = new ConstructingObjectParser<>( - "params", - true, - objects -> new TypedParamValue((String) objects[1], objects[0]) - ); - private static final ParseField VALUE = new ParseField("value"); - private static final ParseField TYPE = new ParseField("type"); + private static class TempObjects { + Map fields = new HashMap<>(); - static { - PARAM_PARSER.declareField(constructorArg(), (p, c) -> parseFieldsValue(p), VALUE, ObjectParser.ValueType.VALUE); - PARAM_PARSER.declareString(constructorArg(), TYPE); + TempObjects() {} + + void addField(String key, Object value) { + fields.put(key, value); + } + + String fields() { + StringBuffer s = new StringBuffer(); + for (Map.Entry entry : fields.entrySet()) { + if (s.length() > 0) { + s.append(", "); + } + s.append("{").append(entry.getKey()).append(":").append(entry.getValue()).append("}"); + } + return s.toString(); + } } + private static final ObjectParser PARAM_PARSER = new ObjectParser<>( + "params", + TempObjects::addField, + TempObjects::new + ); + static final ParseField QUERY_FIELD = new ParseField("query"); private static final ParseField COLUMNAR_FIELD = new ParseField("columnar"); private static final ParseField FILTER_FIELD = new ParseField("filter"); @@ -81,7 +98,7 @@ final class RequestXContent { (p, c) -> new QueryPragmas(Settings.builder().loadFromMap(p.map()).build()), PRAGMA_FIELD ); - parser.declareField(EsqlQueryRequest::params, RequestXContent::parseParams, PARAMS_FIELD, VALUE_ARRAY); + parser.declareField(EsqlQueryRequest::params, RequestXContent::parseParams, PARAMS_FIELD, VALUE_OBJECT_ARRAY); parser.declareString((request, localeTag) -> request.locale(Locale.forLanguageTag(localeTag)), LOCALE_FIELD); parser.declareBoolean(EsqlQueryRequest::profile, PROFILE_FIELD); parser.declareField((p, r, c) -> new ParseTables(r, p).parseTables(), TABLES_FIELD, ObjectParser.ValueType.OBJECT); @@ -112,82 +129,94 @@ final class RequestXContent { return parser; } - private static List parseParams(XContentParser p) throws IOException { - List result = new ArrayList<>(); + private static QueryParams parseParams(XContentParser p) throws IOException { + List namedParams = new ArrayList<>(); + List unNamedParams = new ArrayList<>(); + List errors = new ArrayList<>(); XContentParser.Token token = p.currentToken(); if (token == XContentParser.Token.START_ARRAY) { Object value = null; - String type = null; - TypedParamValue previousParam = null; - TypedParamValue currentParam; + DataType type = null; + QueryParam currentParam = null; + TempObjects param; while ((token = p.nextToken()) != XContentParser.Token.END_ARRAY) { XContentLocation loc = p.getTokenLocation(); - if (token == XContentParser.Token.START_OBJECT) { - // we are at the start of a value/type pair... hopefully - currentParam = PARAM_PARSER.apply(p, null); - /* - * Always set the xcontentlocation for the first param just in case the first one happens to not meet the parsing rules - * that are checked later in validateParams method. - * Also, set the xcontentlocation of the param that is different from the previous param in list when it comes to - * its type being explicitly set or inferred. - */ - if ((previousParam != null && previousParam.hasExplicitType() == false) || result.isEmpty()) { - currentParam.tokenLocation(toProto(loc)); + param = PARAM_PARSER.apply(p, null); + if (param.fields.size() > 1) { + errors.add( + new XContentParseException( + loc, + "Cannot parse more than one key:value pair as parameter, found [" + param.fields() + "]" + ) + ); + } + for (Map.Entry entry : param.fields.entrySet()) { + if (isValidParamName(entry.getKey()) == false) { + errors.add( + new XContentParseException( + loc, + "[" + + entry.getKey() + + "] is not a valid parameter name, " + + "a valid parameter name starts with a letter and contains letters, digits and underscores only" + ) + ); + } + type = EsqlDataTypes.fromJava(entry.getValue()); + if (type == null) { + errors.add(new XContentParseException(loc, entry + " is not supported as a parameter")); + } + currentParam = new QueryParam(entry.getKey(), entry.getValue(), type); + namedParams.add(currentParam); } } else { if (token == XContentParser.Token.VALUE_STRING) { value = p.text(); - type = "keyword"; + type = DataType.KEYWORD; } else if (token == XContentParser.Token.VALUE_NUMBER) { XContentParser.NumberType numberType = p.numberType(); if (numberType == XContentParser.NumberType.INT) { value = p.intValue(); - type = "integer"; + type = DataType.INTEGER; } else if (numberType == XContentParser.NumberType.LONG) { value = p.longValue(); - type = "long"; + type = DataType.LONG; } else if (numberType == XContentParser.NumberType.DOUBLE) { value = p.doubleValue(); - type = "double"; + type = DataType.DOUBLE; } } else if (token == XContentParser.Token.VALUE_BOOLEAN) { value = p.booleanValue(); - type = "boolean"; + type = DataType.BOOLEAN; } else if (token == XContentParser.Token.VALUE_NULL) { value = null; - type = "null"; + type = DataType.NULL; } else { - throw new XContentParseException(loc, "Failed to parse object: unexpected token [" + token + "] found"); - } - - currentParam = new TypedParamValue(type, value, false); - if ((previousParam != null && previousParam.hasExplicitType()) || result.isEmpty()) { - currentParam.tokenLocation(toProto(loc)); + errors.add(new XContentParseException(loc, token + " is not supported as a parameter")); } + currentParam = new QueryParam(null, value, type); + unNamedParams.add(currentParam); } - - result.add(currentParam); - previousParam = currentParam; } } - - return result; - } - - static ContentLocation toProto(org.elasticsearch.xcontent.XContentLocation toProto) { - if (toProto == null) { - return null; + if (namedParams.isEmpty() == false && unNamedParams.isEmpty() == false) { + errors.add( + new XContentParseException( + "Params cannot contain both named and unnamed parameters; got " + + Arrays.toString(namedParams.stream().map(QueryParam::nameValue).toArray()) + + " and " + + Arrays.toString(unNamedParams.stream().map(QueryParam::nameValue).toArray()) + ) + ); } - return new ContentLocation(toProto.lineNumber(), toProto.columnNumber()); - } - - static org.elasticsearch.xcontent.XContentLocation fromProto(ContentLocation fromProto) { - if (fromProto == null) { - return null; + if (errors.size() > 0) { + throw new XContentParseException( + "Failed to parse params: " + String.join("; ", errors.stream().map(ex -> ex.getMessage()).toArray(String[]::new)) + ); } - return new org.elasticsearch.xcontent.XContentLocation(fromProto.lineNumber, fromProto.columnNumber); + return new QueryParams(namedParams.isEmpty() ? unNamedParams : namedParams); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java index 2e29162aebb4..0866f97b6772 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/UnaryScalarFunction.java @@ -7,16 +7,108 @@ package org.elasticsearch.xpack.esql.expression.function.scalar; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.TypeResolutions; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.FromBase64; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToBase64; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToBoolean; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToCartesianPoint; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToCartesianShape; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDatetime; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDegrees; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoPoint; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoShape; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIP; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToRadians; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToString; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToUnsignedLong; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToVersion; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Abs; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Acos; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Asin; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Atan; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cbrt; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Ceil; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cos; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cosh; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Floor; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Log10; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Signum; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Sin; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Sinh; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Sqrt; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Tan; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Tanh; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StY; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.LTrim; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.Length; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.RTrim; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.Trim; +import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Neg; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput; +import java.io.IOException; import java.util.Arrays; +import java.util.List; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNumeric; public abstract class UnaryScalarFunction extends EsqlScalarFunction { + public static List getNamedWriteables() { + return List.of( + Abs.ENTRY, + Acos.ENTRY, + Asin.ENTRY, + Atan.ENTRY, + Cbrt.ENTRY, + Ceil.ENTRY, + Cos.ENTRY, + Cosh.ENTRY, + Floor.ENTRY, + FromBase64.ENTRY, + Length.ENTRY, + Log10.ENTRY, + LTrim.ENTRY, + Neg.ENTRY, + RTrim.ENTRY, + Signum.ENTRY, + Sin.ENTRY, + Sinh.ENTRY, + Sqrt.ENTRY, + StX.ENTRY, + StY.ENTRY, + Tan.ENTRY, + Tanh.ENTRY, + ToBase64.ENTRY, + ToBoolean.ENTRY, + ToCartesianPoint.ENTRY, + ToDatetime.ENTRY, + ToDegrees.ENTRY, + ToDouble.ENTRY, + ToGeoShape.ENTRY, + ToCartesianShape.ENTRY, + ToGeoPoint.ENTRY, + ToIP.ENTRY, + ToInteger.ENTRY, + ToLong.ENTRY, + ToRadians.ENTRY, + ToString.ENTRY, + ToUnsignedLong.ENTRY, + ToVersion.ENTRY, + Trim.ENTRY + ); + } + protected final Expression field; public UnaryScalarFunction(Source source, Expression field) { @@ -24,6 +116,16 @@ public abstract class UnaryScalarFunction extends EsqlScalarFunction { this.field = field; } + protected UnaryScalarFunction(StreamInput in) throws IOException { + this(Source.readFrom((PlanStreamInput) in), ((PlanStreamInput) in).readExpression()); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + source().writeTo(out); + ((PlanStreamOutput) out).writeExpression(field); + } + @Override protected Expression.TypeResolution resolveType() { if (childrenResolved() == false) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java index f1d0256a1f1c..2496d8b82fa6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java @@ -11,6 +11,7 @@ import joptsimple.internal.Strings; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.data.Block; import org.elasticsearch.compute.data.Page; import org.elasticsearch.compute.data.Vector; @@ -24,8 +25,10 @@ import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.Warnings; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; import org.elasticsearch.xpack.esql.type.EsqlDataTypes; +import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -53,6 +56,10 @@ public abstract class AbstractConvertFunction extends UnaryScalarFunction { super(source, field); } + protected AbstractConvertFunction(StreamInput in) throws IOException { + this(Source.readFrom((PlanStreamInput) in), ((PlanStreamInput) in).readExpression()); + } + /** * Build the evaluator given the evaluator a multivalued field. */ diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java index 2ebc3d824a4e..873d496bfc8f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java @@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.ann.Fixed; import org.elasticsearch.compute.operator.EvalOperator; @@ -24,6 +26,7 @@ import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.esql.planner.PlannerUtils; +import java.io.IOException; import java.util.Base64; import java.util.List; import java.util.function.Function; @@ -32,6 +35,11 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isStr import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; public class FromBase64 extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "FromBase64", + FromBase64::new + ); @FunctionInfo( returnType = "keyword", @@ -53,6 +61,15 @@ public class FromBase64 extends UnaryScalarFunction { return isString(field, sourceText(), TypeResolutions.ParamOrdinal.DEFAULT); } + private FromBase64(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public DataType dataType() { return KEYWORD; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java index f24651337550..ab8287413c61 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java @@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.ann.Fixed; import org.elasticsearch.compute.operator.EvalOperator; @@ -24,6 +26,7 @@ import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.esql.planner.PlannerUtils; +import java.io.IOException; import java.util.Base64; import java.util.List; import java.util.function.Function; @@ -32,6 +35,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isStr import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; public class ToBase64 extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToBase64", ToBase64::new); @FunctionInfo( returnType = "keyword", @@ -40,7 +44,15 @@ public class ToBase64 extends UnaryScalarFunction { ) public ToBase64(Source source, @Param(name = "string", type = { "keyword", "text" }, description = "A string.") Expression string) { super(source, string); + } + private ToBase64(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBoolean.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBoolean.java index 5de31b7f114e..06cc99345643 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBoolean.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBoolean.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -31,6 +34,11 @@ import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToBo import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToBoolean; public class ToBoolean extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToBoolean", + ToBoolean::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(BOOLEAN, (field, source) -> field), @@ -62,6 +70,15 @@ public class ToBoolean extends AbstractConvertFunction { super(source, field); } + private ToBoolean(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPoint.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPoint.java index 9a3362c52c0f..60a25fc91d50 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPoint.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPoint.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -26,6 +29,11 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToSpatial; public class ToCartesianPoint extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToCartesianPoint", + ToCartesianPoint::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(CARTESIAN_POINT, (fieldEval, source) -> fieldEval), @@ -52,6 +60,15 @@ public class ToCartesianPoint extends AbstractConvertFunction { super(source, field); } + private ToCartesianPoint(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShape.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShape.java index 03e8c565f342..03ac4bdf4824 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShape.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShape.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -27,6 +30,11 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToSpatial; public class ToCartesianShape extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToCartesianShape", + ToCartesianShape::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(CARTESIAN_POINT, (fieldEval, source) -> fieldEval), @@ -54,6 +62,15 @@ public class ToCartesianShape extends AbstractConvertFunction { super(source, field); } + private ToCartesianShape(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetime.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetime.java index 53c87427b960..917abc9d7716 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetime.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetime.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -30,6 +33,11 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.dateTimeToLong; public class ToDatetime extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToDatetime", + ToDatetime::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(DATETIME, (field, source) -> field), @@ -80,6 +88,15 @@ public class ToDatetime extends AbstractConvertFunction { super(source, field); } + private ToDatetime(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegrees.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegrees.java index af163b6ff878..4eb6662e3e97 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegrees.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegrees.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -18,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -31,6 +34,12 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG; * to degrees. */ public class ToDegrees extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToDegrees", + ToDegrees::new + ); + private static final Map EVALUATORS = Map.ofEntries( Map.entry(DOUBLE, ToDegreesEvaluator.Factory::new), Map.entry(INTEGER, (field, source) -> new ToDegreesEvaluator.Factory(new ToDoubleFromIntEvaluator.Factory(field, source), source)), @@ -57,6 +66,15 @@ public class ToDegrees extends AbstractConvertFunction implements EvaluatorMappe super(source, field); } + private ToDegrees(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDouble.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDouble.java index b30162ef2334..de88281e7dbd 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDouble.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDouble.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -18,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -33,6 +36,7 @@ import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToDo import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToDouble; public class ToDouble extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToDouble", ToDouble::new); private static final Map EVALUATORS = Map.ofEntries( Map.entry(DOUBLE, (fieldEval, source) -> fieldEval), @@ -86,6 +90,15 @@ public class ToDouble extends AbstractConvertFunction { super(source, field); } + private ToDouble(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPoint.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPoint.java index 4692155fc973..51cb08137a58 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPoint.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPoint.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -26,6 +29,11 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToSpatial; public class ToGeoPoint extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToGeoPoint", + ToGeoPoint::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(GEO_POINT, (fieldEval, source) -> fieldEval), @@ -52,6 +60,15 @@ public class ToGeoPoint extends AbstractConvertFunction { super(source, field); } + private ToGeoPoint(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java index 93acd578f86c..00e9fb3e598f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -27,6 +30,11 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToSpatial; public class ToGeoShape extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToGeoShape", + ToGeoShape::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(GEO_POINT, (fieldEval, source) -> fieldEval), @@ -54,6 +62,15 @@ public class ToGeoShape extends AbstractConvertFunction { super(source, field); } + private ToGeoShape(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIP.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIP.java index 92467d98472c..6df85948d94e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIP.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIP.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -26,6 +29,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToIP; public class ToIP extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToIP", ToIP::new); private static final Map EVALUATORS = Map.ofEntries( Map.entry(IP, (field, source) -> field), @@ -58,6 +62,15 @@ public class ToIP extends AbstractConvertFunction { super(source, field); } + private ToIP(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToInteger.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToInteger.java index aa926eee3a55..1785160594a7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToInteger.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToInteger.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -18,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -34,6 +37,11 @@ import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToIn import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToInt; public class ToInteger extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToInteger", + ToInteger::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(INTEGER, (fieldEval, source) -> fieldEval), @@ -76,6 +84,15 @@ public class ToInteger extends AbstractConvertFunction { super(source, field); } + private ToInteger(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java index 182c1c923a96..4811051c3f48 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -18,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -34,6 +37,7 @@ import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToLo import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToLong; public class ToLong extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToLong", ToLong::new); private static final Map EVALUATORS = Map.ofEntries( Map.entry(LONG, (fieldEval, source) -> fieldEval), @@ -86,6 +90,15 @@ public class ToLong extends AbstractConvertFunction { super(source, field); } + private ToLong(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadians.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadians.java index 2fd8ae1eb0bd..a73c75a4e823 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadians.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadians.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -30,6 +33,12 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG; * to radians. */ public class ToRadians extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToRadians", + ToRadians::new + ); + private static final Map EVALUATORS = Map.ofEntries( Map.entry(DOUBLE, ToRadiansEvaluator.Factory::new), Map.entry(INTEGER, (field, source) -> new ToRadiansEvaluator.Factory(new ToDoubleFromIntEvaluator.Factory(field, source), source)), @@ -56,6 +65,15 @@ public class ToRadians extends AbstractConvertFunction implements EvaluatorMappe super(source, field); } + private ToRadians(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java index 141fa067e54e..cb9eae6b5f43 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -18,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -43,6 +46,7 @@ import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLo import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.versionToString; public class ToString extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToString", ToString::new); private static final Map EVALUATORS = Map.ofEntries( Map.entry(KEYWORD, (fieldEval, source) -> fieldEval), @@ -93,6 +97,15 @@ public class ToString extends AbstractConvertFunction implements EvaluatorMapper super(source, v); } + private ToString(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLong.java index ad6e935f7d6a..bfbfcf44b394 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLong.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLong.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -18,6 +20,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -36,6 +39,11 @@ import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.longToUnsi import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToUnsignedLong; public class ToUnsignedLong extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToUnsignedLong", + ToUnsignedLong::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(UNSIGNED_LONG, (fieldEval, source) -> fieldEval), @@ -77,6 +85,15 @@ public class ToUnsignedLong extends AbstractConvertFunction { super(source, field); } + private ToUnsignedLong(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersion.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersion.java index 1941dd00837b..f6002c3c6bb1 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersion.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersion.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -26,6 +29,11 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.VERSION; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToVersion; public class ToVersion extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "ToVersion", + ToVersion::new + ); private static final Map EVALUATORS = Map.ofEntries( Map.entry(VERSION, (fieldEval, source) -> fieldEval), @@ -49,6 +57,15 @@ public class ToVersion extends AbstractConvertFunction { super(source, v); } + private ToVersion(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Map factories() { return EVALUATORS; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Abs.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Abs.java index b821b8449a5a..363b70ef5ed1 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Abs.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Abs.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; @@ -19,10 +21,13 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; public class Abs extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Abs", Abs::new); + @FunctionInfo( returnType = { "double", "integer", "long", "unsigned_long" }, description = "Returns the absolute value.", @@ -39,6 +44,15 @@ public class Abs extends UnaryScalarFunction { super(source, n); } + private Abs(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Evaluator(extraName = "Double") static double process(double fieldVal) { return Math.abs(fieldVal); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbstractTrigonometricFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbstractTrigonometricFunction.java index fee52567d161..8353fe24b3dd 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbstractTrigonometricFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbstractTrigonometricFunction.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -14,6 +15,7 @@ import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.function.Function; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; @@ -27,6 +29,10 @@ abstract class AbstractTrigonometricFunction extends UnaryScalarFunction { super(source, field); } + protected AbstractTrigonometricFunction(StreamInput in) throws IOException { + super(in); + } + /** * Build an evaluator for this function given the evaluator for it's input. */ diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Acos.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Acos.java index e3c83f2f4abc..a87fa8ad48bb 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Acos.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Acos.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Inverse cosine trigonometric function. */ public class Acos extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Acos", Acos::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Inverse_trigonometric_functions[arccosine] of `n` as an angle, expressed in radians.", @@ -38,6 +43,15 @@ public class Acos extends AbstractTrigonometricFunction { super(source, n); } + private Acos(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new AcosEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Asin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Asin.java index bc2de0a5b511..5d8c71a461ca 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Asin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Asin.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Inverse cosine trigonometric function. */ public class Asin extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Asin", Asin::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Inverse_trigonometric_functions[arcsine] of the input\n" @@ -39,6 +44,15 @@ public class Asin extends AbstractTrigonometricFunction { super(source, n); } + private Asin(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new AsinEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Atan.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Atan.java index d840faf6d970..d90b12dfef43 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Atan.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Atan.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Inverse cosine trigonometric function. */ public class Atan extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Atan", Atan::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Inverse_trigonometric_functions[arctangent] of the input\n" @@ -39,6 +44,15 @@ public class Atan extends AbstractTrigonometricFunction { super(source, n); } + private Atan(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new AtanEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cbrt.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cbrt.java index 43c0353de490..364e91aad8b1 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cbrt.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cbrt.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; @@ -19,6 +21,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -27,6 +30,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNum import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToDouble; public class Cbrt extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Cbrt", Cbrt::new); + @FunctionInfo(returnType = "double", description = """ Returns the cube root of a number. The input can be any numeric value, the return value is always a double. Cube roots of infinities are null.""", examples = @Example(file = "math", tag = "cbrt")) @@ -41,6 +46,15 @@ public class Cbrt extends UnaryScalarFunction { super(source, n); } + private Cbrt(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public ExpressionEvaluator.Factory toEvaluator(Function toEvaluator) { var field = toEvaluator.apply(field()); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Ceil.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Ceil.java index 06f092a00e94..7d31cec0e54a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Ceil.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Ceil.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -31,6 +34,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNum *

*/ public class Ceil extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Ceil", Ceil::new); + @FunctionInfo( returnType = { "double", "integer", "long", "unsigned_long" }, description = "Round a number up to the nearest integer.", @@ -49,6 +54,15 @@ public class Ceil extends UnaryScalarFunction { super(source, n); } + private Ceil(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public ExpressionEvaluator.Factory toEvaluator(Function toEvaluator) { if (dataType().isInteger()) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java index 29387606a497..4ae134a8d6c2 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cos.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Cosine trigonometric function. */ public class Cos extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Cos", Cos::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Sine_and_cosine[cosine] of an angle.", @@ -38,6 +43,15 @@ public class Cos extends AbstractTrigonometricFunction { super(source, angle); } + private Cos(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new CosEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java index 5e0a8c9b970f..0cfbc195186f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Cosh.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Cosine hyperbolic function. */ public class Cosh extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Cosh", Cosh::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Hyperbolic_functions[hyperbolic cosine] of an angle.", @@ -38,6 +43,15 @@ public class Cosh extends AbstractTrigonometricFunction { super(source, angle); } + private Cosh(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new CoshEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Floor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Floor.java index 173a8ef15230..73ff0aec2b12 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Floor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Floor.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -17,6 +19,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -31,6 +34,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNum *

*/ public class Floor extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Floor", Floor::new); + @FunctionInfo( returnType = { "double", "integer", "long", "unsigned_long" }, description = "Round a number down to the nearest integer.", @@ -51,6 +56,15 @@ public class Floor extends UnaryScalarFunction { super(source, n); } + private Floor(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public ExpressionEvaluator.Factory toEvaluator(Function toEvaluator) { if (dataType().isInteger()) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10.java index 69b7efac9b7e..ae725f6ed649 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -28,6 +31,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNum import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToDouble; public class Log10 extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Log10", Log10::new); + @FunctionInfo( returnType = "double", description = "Returns the logarithm of a value to base 10. The input can " @@ -47,6 +52,15 @@ public class Log10 extends UnaryScalarFunction { super(source, n); } + private Log10(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public ExpressionEvaluator.Factory toEvaluator(Function toEvaluator) { var field = toEvaluator.apply(field()); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Signum.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Signum.java index 7769e8c6c4a2..e78c2ce90e6c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Signum.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Signum.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; @@ -20,10 +22,13 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; public class Signum extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Signum", Signum::new); + @FunctionInfo( returnType = { "double" }, description = "Returns the sign of the given number.\n" @@ -41,6 +46,15 @@ public class Signum extends UnaryScalarFunction { super(source, n); } + private Signum(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public EvalOperator.ExpressionEvaluator.Factory toEvaluator( Function toEvaluator diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sin.java index 2dd9520ab066..526b17fb3eb2 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sin.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,14 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Sine trigonometric function. */ public class Sin extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Sin", Sin::new); @FunctionInfo( returnType = "double", @@ -39,6 +43,15 @@ public class Sin extends AbstractTrigonometricFunction { super(source, angle); } + private Sin(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new SinEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java index 274fb938f68d..f89e626955d7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sinh.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Sine hyperbolic function. */ public class Sinh extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Sinh", Sinh::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Hyperbolic_functions[hyperbolic sine] of an angle.", @@ -38,6 +43,15 @@ public class Sinh extends AbstractTrigonometricFunction { super(source, angle); } + private Sinh(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new SinhEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sqrt.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sqrt.java index a27929b0b5d0..d1af693d8aa7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sqrt.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Sqrt.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; @@ -19,6 +21,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -27,6 +30,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNum import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.unsignedLongToDouble; public class Sqrt extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Sqrt", Sqrt::new); + @FunctionInfo(returnType = "double", description = """ Returns the square root of a number. The input can be any numeric value, the return value is always a double. Square roots of negative numbers and infinities are null.""", examples = @Example(file = "math", tag = "sqrt")) @@ -41,6 +46,15 @@ public class Sqrt extends UnaryScalarFunction { super(source, n); } + private Sqrt(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public ExpressionEvaluator.Factory toEvaluator(Function toEvaluator) { var field = toEvaluator.apply(field()); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java index e0ae6ff5234e..85cdba0db468 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tan.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Tangent trigonometric function. */ public class Tan extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Tan", Tan::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Sine_and_cosine[Tangent] trigonometric function of an angle.", @@ -38,6 +43,15 @@ public class Tan extends AbstractTrigonometricFunction { super(source, angle); } + private Tan(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new TanEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java index 5d423eaf2dd3..0cd4051968c7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Tanh.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.math; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -16,12 +18,15 @@ import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; +import java.io.IOException; import java.util.List; /** * Tangent hyperbolic function. */ public class Tanh extends AbstractTrigonometricFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Tanh", Tanh::new); + @FunctionInfo( returnType = "double", description = "Returns the {wikipedia}/Hyperbolic_functions[Tangent] hyperbolic function of an angle.", @@ -38,6 +43,15 @@ public class Tanh extends AbstractTrigonometricFunction { super(source, angle); } + private Tanh(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected EvalOperator.ExpressionEvaluator.Factory doubleEvaluator(EvalOperator.ExpressionEvaluator.Factory field) { return new TanhEvaluator.Factory(source(), field); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/package-info.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/package-info.java index bf0e10f817e3..7e7a024ba2c4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/package-info.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/package-info.java @@ -54,7 +54,7 @@ * *
  • * Find a function in this package similar to the one you are working on and copy it to build - * yours. There's some ceremony required in each function class to make it constant foldable + * yours. There's some ceremony required in each function class to make it constant foldable, * and return the right types. Take a stab at these, but don't worry too much about getting * it right. Your function might extend from one of several abstract base classes, all of * those are fine for this guide, but might have special instructions called out later. @@ -104,9 +104,21 @@ *
  • *
  • * Add your function to {@link org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry}. - * This links it into the language and {@code META FUNCTIONS}. Also add your function to - * {@link org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes}. This makes your function - * serializable over the wire. Mostly you can copy existing implementations for both. + * This links it into the language and {@code META FUNCTIONS}. + *
  • + *
  • + * Register your function for serialization. We're in the process of migrating this serialization + * from an older way to the more common, {@link org.elasticsearch.common.io.stream.NamedWriteable}. + *

    + * All subclasses of {@link org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction} + * are migrated and should include a "getWriteableName", "writeTo", and a deserializing constructor. + * They should also include a {@link org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry} + * and it should be linked in {@link org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction}. + *

    + *

    + * Other functions serialized in {@link org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes} + * and you should copy what's done there. + *

    *
  • *
  • * Rerun the {@code CsvTests}. They should find your function and maybe even pass. Add a diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StX.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StX.java index 2af1a353a39d..18046135933b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StX.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StX.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -35,6 +38,8 @@ import static org.elasticsearch.xpack.esql.expression.EsqlTypeResolutions.isSpat * Alternatively it is well described in PostGIS documentation at PostGIS:ST_X. */ public class StX extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "StX", StX::new); + @FunctionInfo( returnType = "double", description = "Extracts the `x` coordinate from the supplied point.\n" @@ -52,6 +57,15 @@ public class StX extends UnaryScalarFunction { super(source, field); } + private StX(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected Expression.TypeResolution resolveType() { return isSpatialPoint(field(), sourceText(), TypeResolutions.ParamOrdinal.DEFAULT); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StY.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StY.java index 266c5f986c52..bf97c3e2a354 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StY.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StY.java @@ -8,6 +8,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -35,6 +38,8 @@ import static org.elasticsearch.xpack.esql.expression.EsqlTypeResolutions.isSpat * Alternatively it is well described in PostGIS documentation at PostGIS:ST_Y. */ public class StY extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "StY", StY::new); + @FunctionInfo( returnType = "double", description = "Extracts the `y` coordinate from the supplied point.\n" @@ -52,6 +57,15 @@ public class StY extends UnaryScalarFunction { super(source, field); } + private StY(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected TypeResolution resolveType() { return isSpatialPoint(field(), sourceText(), TypeResolutions.ParamOrdinal.DEFAULT); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/LTrim.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/LTrim.java index e7e0b69d5149..ece70da51ef1 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/LTrim.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/LTrim.java @@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.string; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.UnicodeUtil; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -29,6 +32,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isStr * Removes leading whitespaces from a string. */ public class LTrim extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "LTrim", LTrim::new); + @FunctionInfo( returnType = { "keyword", "text" }, description = "Removes leading whitespaces from a string.", @@ -45,6 +50,15 @@ public class LTrim extends UnaryScalarFunction { super(source, str); } + private LTrim(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected TypeResolution resolveType() { if (childrenResolved() == false) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java index e2beda9612b0..241eab6d5b90 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Length.java @@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.string; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.UnicodeUtil; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -27,6 +30,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.Param import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; public class Length extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Length", Length::new); @FunctionInfo( returnType = "integer", @@ -44,6 +48,15 @@ public class Length extends UnaryScalarFunction { super(source, field); } + private Length(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override public DataType dataType() { return DataType.INTEGER; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RTrim.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RTrim.java index 9edac22ca643..4c210607cfbe 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RTrim.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RTrim.java @@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.string; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.UnicodeUtil; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -29,6 +32,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isStr * Removes trailing whitespaces from a string. */ public class RTrim extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "RTrim", RTrim::new); + @FunctionInfo( returnType = { "keyword", "text" }, description = "Removes trailing whitespaces from a string.", @@ -45,6 +50,15 @@ public class RTrim extends UnaryScalarFunction { super(source, str); } + private RTrim(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected TypeResolution resolveType() { if (childrenResolved() == false) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Trim.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Trim.java index d7d9019a7fba..36dc3d97992a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Trim.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Trim.java @@ -9,6 +9,8 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.string; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.UnicodeUtil; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -20,6 +22,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.util.List; import java.util.function.Function; @@ -29,6 +32,8 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isStr * Removes leading and trailing whitespaces from a string. */ public final class Trim extends UnaryScalarFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Trim", Trim::new); + @FunctionInfo( returnType = { "keyword", "text" }, description = "Removes leading and trailing whitespaces from a string.", @@ -45,6 +50,15 @@ public final class Trim extends UnaryScalarFunction { super(source, str); } + private Trim(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + @Override protected TypeResolution resolveType() { if (childrenResolved() == false) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/Neg.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/Neg.java index 50fb5c58e200..d1ed5579c448 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/Neg.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/Neg.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; @@ -15,9 +17,9 @@ import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.Warnings; import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; +import java.io.IOException; import java.time.Duration; import java.time.Period; import java.util.List; @@ -30,12 +32,19 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TIME_DURATION; import static org.elasticsearch.xpack.esql.type.EsqlDataTypes.isTemporalAmount; public class Neg extends UnaryScalarFunction { - - private final Warnings warnings; + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Neg", Neg::new); public Neg(Source source, Expression field) { super(source, field); - warnings = new Warnings(source); + } + + public Neg(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNameRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNameRegistry.java index d5eb5984e2e6..15368dc0fdb3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNameRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNameRegistry.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.esql.io.stream; +import org.elasticsearch.common.io.stream.NamedWriteable; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; @@ -80,8 +82,6 @@ public class PlanNameRegistry { record Entry( /** The superclass of a writeable category will be read by a reader. */ Class categoryClass, - /** The concrete class. */ - Class concreteClass, /** A name for the writeable which is unique to the categoryClass. */ String name, /** A writer for non-NamedWriteable class */ @@ -104,7 +104,16 @@ public class PlanNameRegistry { PlanWriter writer, PlanReader reader ) { - return new Entry(categoryClass, concreteClass, PlanNamedTypes.name(concreteClass), writer, reader); + return new Entry(categoryClass, PlanNamedTypes.name(concreteClass), writer, reader); + } + + static Entry of(Class categoryClass, NamedWriteableRegistry.Entry entry) { + return new Entry( + categoryClass, + entry.name, + (o, v) -> categoryClass.cast(v).writeTo(o), + in -> categoryClass.cast(entry.reader.read(in)) + ); } static Entry of( @@ -113,7 +122,7 @@ public class PlanNameRegistry { PlanWriter writer, PlanNamedReader reader ) { - return new Entry(categoryClass, concreteClass, PlanNamedTypes.name(concreteClass), writer, reader); + return new Entry(categoryClass, PlanNamedTypes.name(concreteClass), writer, reader); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java index 20d9907c61ba..795790949f66 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java @@ -12,6 +12,7 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.TransportVersions; import org.elasticsearch.common.TriFunction; import org.elasticsearch.common.io.stream.NamedWriteable; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.lucene.BytesRefs; @@ -26,10 +27,8 @@ import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; import org.elasticsearch.xpack.esql.core.expression.Literal; -import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute; import org.elasticsearch.xpack.esql.core.expression.NamedExpression; import org.elasticsearch.xpack.esql.core.expression.Order; -import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; import org.elasticsearch.xpack.esql.core.expression.function.scalar.ScalarFunction; import org.elasticsearch.xpack.esql.core.expression.predicate.logical.And; import org.elasticsearch.xpack.esql.core.expression.predicate.logical.BinaryLogic; @@ -68,23 +67,6 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFuncti import org.elasticsearch.xpack.esql.expression.function.scalar.conditional.Case; import org.elasticsearch.xpack.esql.expression.function.scalar.conditional.Greatest; import org.elasticsearch.xpack.esql.expression.function.scalar.conditional.Least; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.FromBase64; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToBase64; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToBoolean; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToCartesianPoint; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToCartesianShape; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDatetime; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDegrees; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoPoint; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoShape; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIP; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToRadians; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToString; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToUnsignedLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToVersion; import org.elasticsearch.xpack.esql.expression.function.scalar.date.DateDiff; import org.elasticsearch.xpack.esql.expression.function.scalar.date.DateExtract; import org.elasticsearch.xpack.esql.expression.function.scalar.date.DateFormat; @@ -93,28 +75,12 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.date.DateTrunc; import org.elasticsearch.xpack.esql.expression.function.scalar.date.Now; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.CIDRMatch; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.IpPrefix; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Abs; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Acos; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Asin; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Atan; import org.elasticsearch.xpack.esql.expression.function.scalar.math.Atan2; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cbrt; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Ceil; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cos; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cosh; import org.elasticsearch.xpack.esql.expression.function.scalar.math.E; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Floor; import org.elasticsearch.xpack.esql.expression.function.scalar.math.Log; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Log10; import org.elasticsearch.xpack.esql.expression.function.scalar.math.Pi; import org.elasticsearch.xpack.esql.expression.function.scalar.math.Pow; import org.elasticsearch.xpack.esql.expression.function.scalar.math.Round; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Signum; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Sin; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Sinh; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Sqrt; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Tan; -import org.elasticsearch.xpack.esql.expression.function.scalar.math.Tanh; import org.elasticsearch.xpack.esql.expression.function.scalar.math.Tau; import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.AbstractMultivalueFunction; import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvAppend; @@ -137,16 +103,11 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialDi import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialIntersects; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialWithin; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StY; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Concat; import org.elasticsearch.xpack.esql.expression.function.scalar.string.EndsWith; -import org.elasticsearch.xpack.esql.expression.function.scalar.string.LTrim; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Left; -import org.elasticsearch.xpack.esql.expression.function.scalar.string.Length; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Locate; import org.elasticsearch.xpack.esql.expression.function.scalar.string.RLike; -import org.elasticsearch.xpack.esql.expression.function.scalar.string.RTrim; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Repeat; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Replace; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Right; @@ -155,13 +116,11 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.string.StartsWith import org.elasticsearch.xpack.esql.expression.function.scalar.string.Substring; import org.elasticsearch.xpack.esql.expression.function.scalar.string.ToLower; import org.elasticsearch.xpack.esql.expression.function.scalar.string.ToUpper; -import org.elasticsearch.xpack.esql.expression.function.scalar.string.Trim; import org.elasticsearch.xpack.esql.expression.function.scalar.string.WildcardLike; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Add; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Div; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mod; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mul; -import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Neg; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Sub; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison; @@ -211,6 +170,7 @@ import org.elasticsearch.xpack.esql.plan.physical.ShowExec; import org.elasticsearch.xpack.esql.plan.physical.TopNExec; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -261,7 +221,7 @@ public final class PlanNamedTypes { * Entries have the form: category, name, serializer method, deserializer method. */ public static List namedTypeEntries() { - return List.of( + List declared = List.of( // Physical Plan Nodes of(PhysicalPlan.class, AggregateExec.class, PlanNamedTypes::writeAggregateExec, PlanNamedTypes::readAggregateExec), of(PhysicalPlan.class, DissectExec.class, PlanNamedTypes::writeDissectExec, PlanNamedTypes::readDissectExec), @@ -307,13 +267,6 @@ public final class PlanNamedTypes { of(LogicalPlan.class, OrderBy.class, PlanNamedTypes::writeOrderBy, PlanNamedTypes::readOrderBy), of(LogicalPlan.class, Project.class, PlanNamedTypes::writeProject, PlanNamedTypes::readProject), of(LogicalPlan.class, TopN.class, PlanNamedTypes::writeTopN, PlanNamedTypes::readTopN), - // Attributes - of(Expression.class, FieldAttribute.class, (o, a) -> a.writeTo(o), FieldAttribute::new), - of(Expression.class, ReferenceAttribute.class, (o, a) -> a.writeTo(o), ReferenceAttribute::new), - of(Expression.class, MetadataAttribute.class, (o, a) -> a.writeTo(o), MetadataAttribute::new), - of(Expression.class, UnsupportedAttribute.class, (o, a) -> a.writeTo(o), UnsupportedAttribute::new), - // NamedExpressions - of(Expression.class, Alias.class, (o, a) -> a.writeTo(o), Alias::new), // BinaryComparison of(EsqlBinaryComparison.class, Equals.class, PlanNamedTypes::writeBinComparison, PlanNamedTypes::readBinComparison), of(EsqlBinaryComparison.class, NotEquals.class, PlanNamedTypes::writeBinComparison, PlanNamedTypes::readBinComparison), @@ -340,46 +293,6 @@ public final class PlanNamedTypes { of(QL_UNARY_SCLR_CLS, IsNotNull.class, PlanNamedTypes::writeQLUnaryScalar, PlanNamedTypes::readQLUnaryScalar), of(QL_UNARY_SCLR_CLS, IsNull.class, PlanNamedTypes::writeQLUnaryScalar, PlanNamedTypes::readQLUnaryScalar), of(QL_UNARY_SCLR_CLS, Not.class, PlanNamedTypes::writeQLUnaryScalar, PlanNamedTypes::readQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Neg.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Abs.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Acos.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Asin.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Atan.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Cbrt.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Ceil.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Cos.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Cosh.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Floor.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, FromBase64.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Length.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Log10.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, LTrim.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, RTrim.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Signum.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Sin.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Sinh.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Sqrt.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, StX.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, StY.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Tan.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Tanh.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToBase64.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToBoolean.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToCartesianPoint.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToDatetime.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToDegrees.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToDouble.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToGeoShape.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToCartesianShape.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToGeoPoint.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToIP.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToInteger.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToLong.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToRadians.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToString.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToUnsignedLong.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, ToVersion.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), - of(ESQL_UNARY_SCLR_CLS, Trim.class, PlanNamedTypes::writeESQLUnaryScalar, PlanNamedTypes::readESQLUnaryScalar), // ScalarFunction of(ScalarFunction.class, Atan2.class, PlanNamedTypes::writeAtan2, PlanNamedTypes::readAtan2), of(ScalarFunction.class, Case.class, PlanNamedTypes::writeVararg, PlanNamedTypes::readVarag), @@ -455,6 +368,18 @@ public final class PlanNamedTypes { of(Expression.class, Literal.class, PlanNamedTypes::writeLiteral, PlanNamedTypes::readLiteral), of(Expression.class, Order.class, PlanNamedTypes::writeOrder, PlanNamedTypes::readOrder) ); + List entries = new ArrayList<>(declared); + + // From NamedWriteables + for (NamedWriteableRegistry.Entry e : UnaryScalarFunction.getNamedWriteables()) { + entries.add(of(ESQL_UNARY_SCLR_CLS, e)); + } + for (NamedWriteableRegistry.Entry e : NamedExpression.getNamedWriteables()) { + entries.add(of(Expression.class, e)); + } + entries.add(of(Expression.class, UnsupportedAttribute.ENTRY)); + + return entries; } // -- physical plan nodes @@ -1172,64 +1097,6 @@ public final class PlanNamedTypes { out.writeExpression(binaryLogic.right()); } - // -- UnaryScalarFunction - - static final Map> ESQL_UNARY_SCALAR_CTRS = Map.ofEntries( - entry(name(Abs.class), Abs::new), - entry(name(Acos.class), Acos::new), - entry(name(Asin.class), Asin::new), - entry(name(Atan.class), Atan::new), - entry(name(Cbrt.class), Cbrt::new), - entry(name(Ceil.class), Ceil::new), - entry(name(Cos.class), Cos::new), - entry(name(Cosh.class), Cosh::new), - entry(name(Floor.class), Floor::new), - entry(name(FromBase64.class), FromBase64::new), - entry(name(Length.class), Length::new), - entry(name(Log10.class), Log10::new), - entry(name(LTrim.class), LTrim::new), - entry(name(RTrim.class), RTrim::new), - entry(name(Neg.class), Neg::new), - entry(name(Signum.class), Signum::new), - entry(name(Sin.class), Sin::new), - entry(name(Sinh.class), Sinh::new), - entry(name(Sqrt.class), Sqrt::new), - entry(name(StX.class), StX::new), - entry(name(StY.class), StY::new), - entry(name(Tan.class), Tan::new), - entry(name(Tanh.class), Tanh::new), - entry(name(ToBase64.class), ToBase64::new), - entry(name(ToBoolean.class), ToBoolean::new), - entry(name(ToCartesianPoint.class), ToCartesianPoint::new), - entry(name(ToDatetime.class), ToDatetime::new), - entry(name(ToDegrees.class), ToDegrees::new), - entry(name(ToDouble.class), ToDouble::new), - entry(name(ToGeoShape.class), ToGeoShape::new), - entry(name(ToCartesianShape.class), ToCartesianShape::new), - entry(name(ToGeoPoint.class), ToGeoPoint::new), - entry(name(ToIP.class), ToIP::new), - entry(name(ToInteger.class), ToInteger::new), - entry(name(ToLong.class), ToLong::new), - entry(name(ToRadians.class), ToRadians::new), - entry(name(ToString.class), ToString::new), - entry(name(ToUnsignedLong.class), ToUnsignedLong::new), - entry(name(ToVersion.class), ToVersion::new), - entry(name(Trim.class), Trim::new) - ); - - static UnaryScalarFunction readESQLUnaryScalar(PlanStreamInput in, String name) throws IOException { - var ctr = ESQL_UNARY_SCALAR_CTRS.get(name); - if (ctr == null) { - throw new IOException("Constructor for ESQLUnaryScalar not found for name:" + name); - } - return ctr.apply(Source.readFrom(in), in.readExpression()); - } - - static void writeESQLUnaryScalar(PlanStreamOutput out, UnaryScalarFunction function) throws IOException { - function.source().writeTo(out); - out.writeExpression(function.field()); - } - static final Map> NO_ARG_SCALAR_CTRS = Map.ofEntries( entry(name(E.class), E::new), entry(name(Pi.class), Pi::new), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java index 406b9e21e1d5..3b39e6a9d1fd 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java @@ -7,12 +7,8 @@ package org.elasticsearch.xpack.esql.parser; -import org.antlr.v4.runtime.Token; - -import java.util.Map; - public class AstBuilder extends LogicalPlanBuilder { - public AstBuilder(Map params) { + public AstBuilder(QueryParams params) { super(params); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ContentLocation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ContentLocation.java deleted file mode 100644 index 6b1b50df32f5..000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ContentLocation.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.parser; - -/** - * Light clone of XContentLocation - */ -public class ContentLocation { - - public static final ContentLocation UNKNOWN = new ContentLocation(-1, -1); - - public final int lineNumber; - public final int columnNumber; - - public ContentLocation(int lineNumber, int columnNumber) { - super(); - this.lineNumber = lineNumber; - this.columnNumber = columnNumber; - } - - @Override - public String toString() { - return lineNumber + ":" + columnNumber; - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp index 6f9e20e95430..eb3689d0900d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp @@ -68,6 +68,7 @@ null '/' '%' null +null ']' null null @@ -193,6 +194,7 @@ MINUS ASTERISK SLASH PERCENT +NAMED_OR_POSITIONAL_PARAM OPENING_BRACKET CLOSING_BRACKET UNQUOTED_IDENTIFIER @@ -331,6 +333,7 @@ MINUS ASTERISK SLASH PERCENT +NAMED_OR_POSITIONAL_PARAM OPENING_BRACKET CLOSING_BRACKET UNQUOTED_IDENTIFIER @@ -464,4 +467,4 @@ METRICS_MODE CLOSING_METRICS_MODE atn: -[4, 0, 123, 1404, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 4, 20, 565, 8, 20, 11, 20, 12, 20, 566, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 575, 8, 21, 10, 21, 12, 21, 578, 9, 21, 1, 21, 3, 21, 581, 8, 21, 1, 21, 3, 21, 584, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 593, 8, 22, 10, 22, 12, 22, 596, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 4, 23, 604, 8, 23, 11, 23, 12, 23, 605, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 3, 24, 613, 8, 24, 1, 25, 4, 25, 616, 8, 25, 11, 25, 12, 25, 617, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 3, 36, 657, 8, 36, 1, 36, 4, 36, 660, 8, 36, 11, 36, 12, 36, 661, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 3, 39, 671, 8, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 3, 41, 678, 8, 41, 1, 42, 1, 42, 1, 42, 5, 42, 683, 8, 42, 10, 42, 12, 42, 686, 9, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 694, 8, 42, 10, 42, 12, 42, 697, 9, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 704, 8, 42, 1, 42, 3, 42, 707, 8, 42, 3, 42, 709, 8, 42, 1, 43, 4, 43, 712, 8, 43, 11, 43, 12, 43, 713, 1, 44, 4, 44, 717, 8, 44, 11, 44, 12, 44, 718, 1, 44, 1, 44, 5, 44, 723, 8, 44, 10, 44, 12, 44, 726, 9, 44, 1, 44, 1, 44, 4, 44, 730, 8, 44, 11, 44, 12, 44, 731, 1, 44, 4, 44, 735, 8, 44, 11, 44, 12, 44, 736, 1, 44, 1, 44, 5, 44, 741, 8, 44, 10, 44, 12, 44, 744, 9, 44, 3, 44, 746, 8, 44, 1, 44, 1, 44, 1, 44, 1, 44, 4, 44, 752, 8, 44, 11, 44, 12, 44, 753, 1, 44, 1, 44, 3, 44, 758, 8, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 5, 82, 889, 8, 82, 10, 82, 12, 82, 892, 9, 82, 1, 82, 1, 82, 3, 82, 896, 8, 82, 1, 82, 4, 82, 899, 8, 82, 11, 82, 12, 82, 900, 3, 82, 903, 8, 82, 1, 83, 1, 83, 4, 83, 907, 8, 83, 11, 83, 12, 83, 908, 1, 83, 1, 83, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 3, 102, 994, 8, 102, 1, 103, 1, 103, 3, 103, 998, 8, 103, 1, 103, 5, 103, 1001, 8, 103, 10, 103, 12, 103, 1004, 9, 103, 1, 103, 1, 103, 3, 103, 1008, 8, 103, 1, 103, 4, 103, 1011, 8, 103, 11, 103, 12, 103, 1012, 3, 103, 1015, 8, 103, 1, 104, 1, 104, 4, 104, 1019, 8, 104, 11, 104, 12, 104, 1020, 1, 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 122, 4, 122, 1096, 8, 122, 11, 122, 12, 122, 1097, 1, 122, 1, 122, 3, 122, 1102, 8, 122, 1, 122, 4, 122, 1105, 8, 122, 11, 122, 12, 122, 1106, 1, 123, 1, 123, 1, 123, 1, 123, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 1, 129, 1, 129, 1, 129, 1, 129, 1, 130, 1, 130, 1, 130, 1, 130, 1, 131, 1, 131, 1, 131, 1, 131, 1, 132, 1, 132, 1, 132, 1, 132, 1, 133, 1, 133, 1, 133, 1, 133, 1, 134, 1, 134, 1, 134, 1, 134, 1, 135, 1, 135, 1, 135, 1, 135, 1, 136, 1, 136, 1, 136, 1, 136, 1, 137, 1, 137, 1, 137, 1, 137, 1, 138, 1, 138, 1, 138, 1, 138, 1, 138, 1, 139, 1, 139, 1, 139, 1, 139, 1, 140, 1, 140, 1, 140, 1, 140, 1, 141, 1, 141, 1, 141, 1, 141, 1, 141, 1, 142, 1, 142, 1, 142, 1, 142, 1, 143, 1, 143, 1, 143, 1, 143, 1, 144, 1, 144, 1, 144, 1, 144, 1, 145, 1, 145, 1, 145, 1, 145, 1, 146, 1, 146, 1, 146, 1, 146, 1, 146, 1, 146, 1, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 1, 158, 1, 158, 1, 158, 1, 159, 1, 159, 1, 159, 1, 159, 1, 160, 1, 160, 1, 160, 1, 160, 1, 160, 1, 161, 1, 161, 1, 161, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 172, 1, 172, 1, 172, 1, 172, 1, 172, 4, 172, 1325, 8, 172, 11, 172, 12, 172, 1326, 1, 173, 1, 173, 1, 173, 1, 173, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 177, 1, 177, 1, 178, 1, 178, 1, 178, 1, 178, 1, 179, 1, 179, 1, 179, 1, 179, 1, 180, 1, 180, 1, 180, 1, 180, 1, 181, 1, 181, 1, 181, 1, 181, 1, 181, 1, 181, 1, 182, 1, 182, 1, 182, 1, 182, 1, 183, 1, 183, 1, 183, 1, 183, 1, 184, 1, 184, 1, 184, 1, 184, 1, 185, 1, 185, 1, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 1, 187, 1, 187, 1, 187, 1, 187, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 2, 594, 695, 0, 189, 16, 1, 18, 2, 20, 3, 22, 4, 24, 5, 26, 6, 28, 7, 30, 8, 32, 9, 34, 10, 36, 11, 38, 12, 40, 13, 42, 14, 44, 15, 46, 16, 48, 17, 50, 18, 52, 19, 54, 20, 56, 21, 58, 22, 60, 23, 62, 24, 64, 0, 66, 25, 68, 0, 70, 0, 72, 26, 74, 27, 76, 28, 78, 29, 80, 0, 82, 0, 84, 0, 86, 0, 88, 0, 90, 0, 92, 0, 94, 0, 96, 0, 98, 0, 100, 30, 102, 31, 104, 32, 106, 33, 108, 34, 110, 35, 112, 36, 114, 37, 116, 38, 118, 39, 120, 40, 122, 41, 124, 42, 126, 43, 128, 44, 130, 45, 132, 46, 134, 47, 136, 48, 138, 49, 140, 50, 142, 51, 144, 52, 146, 53, 148, 54, 150, 55, 152, 56, 154, 57, 156, 58, 158, 59, 160, 60, 162, 61, 164, 62, 166, 63, 168, 64, 170, 65, 172, 66, 174, 67, 176, 68, 178, 69, 180, 70, 182, 0, 184, 71, 186, 72, 188, 73, 190, 74, 192, 0, 194, 0, 196, 0, 198, 0, 200, 0, 202, 0, 204, 75, 206, 0, 208, 76, 210, 77, 212, 78, 214, 0, 216, 0, 218, 0, 220, 0, 222, 0, 224, 79, 226, 80, 228, 81, 230, 82, 232, 0, 234, 0, 236, 0, 238, 0, 240, 83, 242, 0, 244, 84, 246, 85, 248, 86, 250, 0, 252, 0, 254, 87, 256, 88, 258, 0, 260, 89, 262, 0, 264, 0, 266, 90, 268, 91, 270, 92, 272, 0, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286, 93, 288, 94, 290, 95, 292, 0, 294, 0, 296, 0, 298, 0, 300, 0, 302, 96, 304, 97, 306, 98, 308, 0, 310, 0, 312, 0, 314, 0, 316, 99, 318, 100, 320, 101, 322, 0, 324, 0, 326, 0, 328, 0, 330, 102, 332, 103, 334, 104, 336, 0, 338, 105, 340, 106, 342, 107, 344, 108, 346, 0, 348, 109, 350, 110, 352, 111, 354, 112, 356, 0, 358, 113, 360, 114, 362, 115, 364, 116, 366, 117, 368, 0, 370, 0, 372, 118, 374, 119, 376, 120, 378, 0, 380, 121, 382, 122, 384, 123, 386, 0, 388, 0, 390, 0, 392, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 13, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 10, 0, 9, 10, 13, 13, 32, 32, 44, 44, 47, 47, 61, 61, 91, 91, 93, 93, 96, 96, 124, 124, 2, 0, 42, 42, 47, 47, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 5, 0, 34, 34, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 1, 0, 96, 96, 11, 0, 9, 10, 13, 13, 32, 32, 34, 35, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1427, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 66, 1, 0, 0, 0, 1, 68, 1, 0, 0, 0, 1, 70, 1, 0, 0, 0, 1, 72, 1, 0, 0, 0, 1, 74, 1, 0, 0, 0, 1, 76, 1, 0, 0, 0, 2, 78, 1, 0, 0, 0, 2, 100, 1, 0, 0, 0, 2, 102, 1, 0, 0, 0, 2, 104, 1, 0, 0, 0, 2, 106, 1, 0, 0, 0, 2, 108, 1, 0, 0, 0, 2, 110, 1, 0, 0, 0, 2, 112, 1, 0, 0, 0, 2, 114, 1, 0, 0, 0, 2, 116, 1, 0, 0, 0, 2, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 124, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 128, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 2, 138, 1, 0, 0, 0, 2, 140, 1, 0, 0, 0, 2, 142, 1, 0, 0, 0, 2, 144, 1, 0, 0, 0, 2, 146, 1, 0, 0, 0, 2, 148, 1, 0, 0, 0, 2, 150, 1, 0, 0, 0, 2, 152, 1, 0, 0, 0, 2, 154, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 2, 158, 1, 0, 0, 0, 2, 160, 1, 0, 0, 0, 2, 162, 1, 0, 0, 0, 2, 164, 1, 0, 0, 0, 2, 166, 1, 0, 0, 0, 2, 168, 1, 0, 0, 0, 2, 170, 1, 0, 0, 0, 2, 172, 1, 0, 0, 0, 2, 174, 1, 0, 0, 0, 2, 176, 1, 0, 0, 0, 2, 178, 1, 0, 0, 0, 2, 180, 1, 0, 0, 0, 2, 184, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 2, 188, 1, 0, 0, 0, 2, 190, 1, 0, 0, 0, 3, 192, 1, 0, 0, 0, 3, 194, 1, 0, 0, 0, 3, 196, 1, 0, 0, 0, 3, 198, 1, 0, 0, 0, 3, 200, 1, 0, 0, 0, 3, 202, 1, 0, 0, 0, 3, 204, 1, 0, 0, 0, 3, 206, 1, 0, 0, 0, 3, 208, 1, 0, 0, 0, 3, 210, 1, 0, 0, 0, 3, 212, 1, 0, 0, 0, 4, 214, 1, 0, 0, 0, 4, 216, 1, 0, 0, 0, 4, 218, 1, 0, 0, 0, 4, 224, 1, 0, 0, 0, 4, 226, 1, 0, 0, 0, 4, 228, 1, 0, 0, 0, 4, 230, 1, 0, 0, 0, 5, 232, 1, 0, 0, 0, 5, 234, 1, 0, 0, 0, 5, 236, 1, 0, 0, 0, 5, 238, 1, 0, 0, 0, 5, 240, 1, 0, 0, 0, 5, 242, 1, 0, 0, 0, 5, 244, 1, 0, 0, 0, 5, 246, 1, 0, 0, 0, 5, 248, 1, 0, 0, 0, 6, 250, 1, 0, 0, 0, 6, 252, 1, 0, 0, 0, 6, 254, 1, 0, 0, 0, 6, 256, 1, 0, 0, 0, 6, 260, 1, 0, 0, 0, 6, 262, 1, 0, 0, 0, 6, 264, 1, 0, 0, 0, 6, 266, 1, 0, 0, 0, 6, 268, 1, 0, 0, 0, 6, 270, 1, 0, 0, 0, 7, 272, 1, 0, 0, 0, 7, 274, 1, 0, 0, 0, 7, 276, 1, 0, 0, 0, 7, 278, 1, 0, 0, 0, 7, 280, 1, 0, 0, 0, 7, 282, 1, 0, 0, 0, 7, 284, 1, 0, 0, 0, 7, 286, 1, 0, 0, 0, 7, 288, 1, 0, 0, 0, 7, 290, 1, 0, 0, 0, 8, 292, 1, 0, 0, 0, 8, 294, 1, 0, 0, 0, 8, 296, 1, 0, 0, 0, 8, 298, 1, 0, 0, 0, 8, 300, 1, 0, 0, 0, 8, 302, 1, 0, 0, 0, 8, 304, 1, 0, 0, 0, 8, 306, 1, 0, 0, 0, 9, 308, 1, 0, 0, 0, 9, 310, 1, 0, 0, 0, 9, 312, 1, 0, 0, 0, 9, 314, 1, 0, 0, 0, 9, 316, 1, 0, 0, 0, 9, 318, 1, 0, 0, 0, 9, 320, 1, 0, 0, 0, 10, 322, 1, 0, 0, 0, 10, 324, 1, 0, 0, 0, 10, 326, 1, 0, 0, 0, 10, 328, 1, 0, 0, 0, 10, 330, 1, 0, 0, 0, 10, 332, 1, 0, 0, 0, 10, 334, 1, 0, 0, 0, 11, 336, 1, 0, 0, 0, 11, 338, 1, 0, 0, 0, 11, 340, 1, 0, 0, 0, 11, 342, 1, 0, 0, 0, 11, 344, 1, 0, 0, 0, 12, 346, 1, 0, 0, 0, 12, 348, 1, 0, 0, 0, 12, 350, 1, 0, 0, 0, 12, 352, 1, 0, 0, 0, 12, 354, 1, 0, 0, 0, 13, 356, 1, 0, 0, 0, 13, 358, 1, 0, 0, 0, 13, 360, 1, 0, 0, 0, 13, 362, 1, 0, 0, 0, 13, 364, 1, 0, 0, 0, 13, 366, 1, 0, 0, 0, 14, 368, 1, 0, 0, 0, 14, 370, 1, 0, 0, 0, 14, 372, 1, 0, 0, 0, 14, 374, 1, 0, 0, 0, 14, 376, 1, 0, 0, 0, 15, 378, 1, 0, 0, 0, 15, 380, 1, 0, 0, 0, 15, 382, 1, 0, 0, 0, 15, 384, 1, 0, 0, 0, 15, 386, 1, 0, 0, 0, 15, 388, 1, 0, 0, 0, 15, 390, 1, 0, 0, 0, 15, 392, 1, 0, 0, 0, 16, 394, 1, 0, 0, 0, 18, 404, 1, 0, 0, 0, 20, 411, 1, 0, 0, 0, 22, 420, 1, 0, 0, 0, 24, 427, 1, 0, 0, 0, 26, 437, 1, 0, 0, 0, 28, 444, 1, 0, 0, 0, 30, 451, 1, 0, 0, 0, 32, 465, 1, 0, 0, 0, 34, 472, 1, 0, 0, 0, 36, 480, 1, 0, 0, 0, 38, 489, 1, 0, 0, 0, 40, 496, 1, 0, 0, 0, 42, 506, 1, 0, 0, 0, 44, 518, 1, 0, 0, 0, 46, 527, 1, 0, 0, 0, 48, 533, 1, 0, 0, 0, 50, 540, 1, 0, 0, 0, 52, 547, 1, 0, 0, 0, 54, 555, 1, 0, 0, 0, 56, 564, 1, 0, 0, 0, 58, 570, 1, 0, 0, 0, 60, 587, 1, 0, 0, 0, 62, 603, 1, 0, 0, 0, 64, 612, 1, 0, 0, 0, 66, 615, 1, 0, 0, 0, 68, 619, 1, 0, 0, 0, 70, 624, 1, 0, 0, 0, 72, 629, 1, 0, 0, 0, 74, 633, 1, 0, 0, 0, 76, 637, 1, 0, 0, 0, 78, 641, 1, 0, 0, 0, 80, 645, 1, 0, 0, 0, 82, 647, 1, 0, 0, 0, 84, 649, 1, 0, 0, 0, 86, 652, 1, 0, 0, 0, 88, 654, 1, 0, 0, 0, 90, 663, 1, 0, 0, 0, 92, 665, 1, 0, 0, 0, 94, 670, 1, 0, 0, 0, 96, 672, 1, 0, 0, 0, 98, 677, 1, 0, 0, 0, 100, 708, 1, 0, 0, 0, 102, 711, 1, 0, 0, 0, 104, 757, 1, 0, 0, 0, 106, 759, 1, 0, 0, 0, 108, 762, 1, 0, 0, 0, 110, 766, 1, 0, 0, 0, 112, 770, 1, 0, 0, 0, 114, 772, 1, 0, 0, 0, 116, 775, 1, 0, 0, 0, 118, 777, 1, 0, 0, 0, 120, 782, 1, 0, 0, 0, 122, 784, 1, 0, 0, 0, 124, 790, 1, 0, 0, 0, 126, 796, 1, 0, 0, 0, 128, 801, 1, 0, 0, 0, 130, 803, 1, 0, 0, 0, 132, 806, 1, 0, 0, 0, 134, 809, 1, 0, 0, 0, 136, 814, 1, 0, 0, 0, 138, 818, 1, 0, 0, 0, 140, 823, 1, 0, 0, 0, 142, 829, 1, 0, 0, 0, 144, 832, 1, 0, 0, 0, 146, 834, 1, 0, 0, 0, 148, 840, 1, 0, 0, 0, 150, 842, 1, 0, 0, 0, 152, 847, 1, 0, 0, 0, 154, 850, 1, 0, 0, 0, 156, 853, 1, 0, 0, 0, 158, 856, 1, 0, 0, 0, 160, 858, 1, 0, 0, 0, 162, 861, 1, 0, 0, 0, 164, 863, 1, 0, 0, 0, 166, 866, 1, 0, 0, 0, 168, 868, 1, 0, 0, 0, 170, 870, 1, 0, 0, 0, 172, 872, 1, 0, 0, 0, 174, 874, 1, 0, 0, 0, 176, 876, 1, 0, 0, 0, 178, 881, 1, 0, 0, 0, 180, 902, 1, 0, 0, 0, 182, 904, 1, 0, 0, 0, 184, 912, 1, 0, 0, 0, 186, 914, 1, 0, 0, 0, 188, 918, 1, 0, 0, 0, 190, 922, 1, 0, 0, 0, 192, 926, 1, 0, 0, 0, 194, 931, 1, 0, 0, 0, 196, 935, 1, 0, 0, 0, 198, 939, 1, 0, 0, 0, 200, 943, 1, 0, 0, 0, 202, 947, 1, 0, 0, 0, 204, 951, 1, 0, 0, 0, 206, 960, 1, 0, 0, 0, 208, 964, 1, 0, 0, 0, 210, 968, 1, 0, 0, 0, 212, 972, 1, 0, 0, 0, 214, 976, 1, 0, 0, 0, 216, 981, 1, 0, 0, 0, 218, 985, 1, 0, 0, 0, 220, 993, 1, 0, 0, 0, 222, 1014, 1, 0, 0, 0, 224, 1018, 1, 0, 0, 0, 226, 1022, 1, 0, 0, 0, 228, 1026, 1, 0, 0, 0, 230, 1030, 1, 0, 0, 0, 232, 1034, 1, 0, 0, 0, 234, 1039, 1, 0, 0, 0, 236, 1043, 1, 0, 0, 0, 238, 1047, 1, 0, 0, 0, 240, 1051, 1, 0, 0, 0, 242, 1054, 1, 0, 0, 0, 244, 1058, 1, 0, 0, 0, 246, 1062, 1, 0, 0, 0, 248, 1066, 1, 0, 0, 0, 250, 1070, 1, 0, 0, 0, 252, 1075, 1, 0, 0, 0, 254, 1080, 1, 0, 0, 0, 256, 1085, 1, 0, 0, 0, 258, 1092, 1, 0, 0, 0, 260, 1101, 1, 0, 0, 0, 262, 1108, 1, 0, 0, 0, 264, 1112, 1, 0, 0, 0, 266, 1116, 1, 0, 0, 0, 268, 1120, 1, 0, 0, 0, 270, 1124, 1, 0, 0, 0, 272, 1128, 1, 0, 0, 0, 274, 1134, 1, 0, 0, 0, 276, 1138, 1, 0, 0, 0, 278, 1142, 1, 0, 0, 0, 280, 1146, 1, 0, 0, 0, 282, 1150, 1, 0, 0, 0, 284, 1154, 1, 0, 0, 0, 286, 1158, 1, 0, 0, 0, 288, 1162, 1, 0, 0, 0, 290, 1166, 1, 0, 0, 0, 292, 1170, 1, 0, 0, 0, 294, 1175, 1, 0, 0, 0, 296, 1179, 1, 0, 0, 0, 298, 1183, 1, 0, 0, 0, 300, 1188, 1, 0, 0, 0, 302, 1192, 1, 0, 0, 0, 304, 1196, 1, 0, 0, 0, 306, 1200, 1, 0, 0, 0, 308, 1204, 1, 0, 0, 0, 310, 1210, 1, 0, 0, 0, 312, 1214, 1, 0, 0, 0, 314, 1218, 1, 0, 0, 0, 316, 1222, 1, 0, 0, 0, 318, 1226, 1, 0, 0, 0, 320, 1230, 1, 0, 0, 0, 322, 1234, 1, 0, 0, 0, 324, 1239, 1, 0, 0, 0, 326, 1243, 1, 0, 0, 0, 328, 1247, 1, 0, 0, 0, 330, 1251, 1, 0, 0, 0, 332, 1255, 1, 0, 0, 0, 334, 1259, 1, 0, 0, 0, 336, 1263, 1, 0, 0, 0, 338, 1268, 1, 0, 0, 0, 340, 1273, 1, 0, 0, 0, 342, 1277, 1, 0, 0, 0, 344, 1281, 1, 0, 0, 0, 346, 1285, 1, 0, 0, 0, 348, 1290, 1, 0, 0, 0, 350, 1300, 1, 0, 0, 0, 352, 1304, 1, 0, 0, 0, 354, 1308, 1, 0, 0, 0, 356, 1312, 1, 0, 0, 0, 358, 1317, 1, 0, 0, 0, 360, 1324, 1, 0, 0, 0, 362, 1328, 1, 0, 0, 0, 364, 1332, 1, 0, 0, 0, 366, 1336, 1, 0, 0, 0, 368, 1340, 1, 0, 0, 0, 370, 1345, 1, 0, 0, 0, 372, 1351, 1, 0, 0, 0, 374, 1355, 1, 0, 0, 0, 376, 1359, 1, 0, 0, 0, 378, 1363, 1, 0, 0, 0, 380, 1369, 1, 0, 0, 0, 382, 1373, 1, 0, 0, 0, 384, 1377, 1, 0, 0, 0, 386, 1381, 1, 0, 0, 0, 388, 1387, 1, 0, 0, 0, 390, 1393, 1, 0, 0, 0, 392, 1399, 1, 0, 0, 0, 394, 395, 5, 100, 0, 0, 395, 396, 5, 105, 0, 0, 396, 397, 5, 115, 0, 0, 397, 398, 5, 115, 0, 0, 398, 399, 5, 101, 0, 0, 399, 400, 5, 99, 0, 0, 400, 401, 5, 116, 0, 0, 401, 402, 1, 0, 0, 0, 402, 403, 6, 0, 0, 0, 403, 17, 1, 0, 0, 0, 404, 405, 5, 100, 0, 0, 405, 406, 5, 114, 0, 0, 406, 407, 5, 111, 0, 0, 407, 408, 5, 112, 0, 0, 408, 409, 1, 0, 0, 0, 409, 410, 6, 1, 1, 0, 410, 19, 1, 0, 0, 0, 411, 412, 5, 101, 0, 0, 412, 413, 5, 110, 0, 0, 413, 414, 5, 114, 0, 0, 414, 415, 5, 105, 0, 0, 415, 416, 5, 99, 0, 0, 416, 417, 5, 104, 0, 0, 417, 418, 1, 0, 0, 0, 418, 419, 6, 2, 2, 0, 419, 21, 1, 0, 0, 0, 420, 421, 5, 101, 0, 0, 421, 422, 5, 118, 0, 0, 422, 423, 5, 97, 0, 0, 423, 424, 5, 108, 0, 0, 424, 425, 1, 0, 0, 0, 425, 426, 6, 3, 0, 0, 426, 23, 1, 0, 0, 0, 427, 428, 5, 101, 0, 0, 428, 429, 5, 120, 0, 0, 429, 430, 5, 112, 0, 0, 430, 431, 5, 108, 0, 0, 431, 432, 5, 97, 0, 0, 432, 433, 5, 105, 0, 0, 433, 434, 5, 110, 0, 0, 434, 435, 1, 0, 0, 0, 435, 436, 6, 4, 3, 0, 436, 25, 1, 0, 0, 0, 437, 438, 5, 102, 0, 0, 438, 439, 5, 114, 0, 0, 439, 440, 5, 111, 0, 0, 440, 441, 5, 109, 0, 0, 441, 442, 1, 0, 0, 0, 442, 443, 6, 5, 4, 0, 443, 27, 1, 0, 0, 0, 444, 445, 5, 103, 0, 0, 445, 446, 5, 114, 0, 0, 446, 447, 5, 111, 0, 0, 447, 448, 5, 107, 0, 0, 448, 449, 1, 0, 0, 0, 449, 450, 6, 6, 0, 0, 450, 29, 1, 0, 0, 0, 451, 452, 5, 105, 0, 0, 452, 453, 5, 110, 0, 0, 453, 454, 5, 108, 0, 0, 454, 455, 5, 105, 0, 0, 455, 456, 5, 110, 0, 0, 456, 457, 5, 101, 0, 0, 457, 458, 5, 115, 0, 0, 458, 459, 5, 116, 0, 0, 459, 460, 5, 97, 0, 0, 460, 461, 5, 116, 0, 0, 461, 462, 5, 115, 0, 0, 462, 463, 1, 0, 0, 0, 463, 464, 6, 7, 0, 0, 464, 31, 1, 0, 0, 0, 465, 466, 5, 107, 0, 0, 466, 467, 5, 101, 0, 0, 467, 468, 5, 101, 0, 0, 468, 469, 5, 112, 0, 0, 469, 470, 1, 0, 0, 0, 470, 471, 6, 8, 1, 0, 471, 33, 1, 0, 0, 0, 472, 473, 5, 108, 0, 0, 473, 474, 5, 105, 0, 0, 474, 475, 5, 109, 0, 0, 475, 476, 5, 105, 0, 0, 476, 477, 5, 116, 0, 0, 477, 478, 1, 0, 0, 0, 478, 479, 6, 9, 0, 0, 479, 35, 1, 0, 0, 0, 480, 481, 5, 108, 0, 0, 481, 482, 5, 111, 0, 0, 482, 483, 5, 111, 0, 0, 483, 484, 5, 107, 0, 0, 484, 485, 5, 117, 0, 0, 485, 486, 5, 112, 0, 0, 486, 487, 1, 0, 0, 0, 487, 488, 6, 10, 5, 0, 488, 37, 1, 0, 0, 0, 489, 490, 5, 109, 0, 0, 490, 491, 5, 101, 0, 0, 491, 492, 5, 116, 0, 0, 492, 493, 5, 97, 0, 0, 493, 494, 1, 0, 0, 0, 494, 495, 6, 11, 6, 0, 495, 39, 1, 0, 0, 0, 496, 497, 5, 109, 0, 0, 497, 498, 5, 101, 0, 0, 498, 499, 5, 116, 0, 0, 499, 500, 5, 114, 0, 0, 500, 501, 5, 105, 0, 0, 501, 502, 5, 99, 0, 0, 502, 503, 5, 115, 0, 0, 503, 504, 1, 0, 0, 0, 504, 505, 6, 12, 7, 0, 505, 41, 1, 0, 0, 0, 506, 507, 5, 109, 0, 0, 507, 508, 5, 118, 0, 0, 508, 509, 5, 95, 0, 0, 509, 510, 5, 101, 0, 0, 510, 511, 5, 120, 0, 0, 511, 512, 5, 112, 0, 0, 512, 513, 5, 97, 0, 0, 513, 514, 5, 110, 0, 0, 514, 515, 5, 100, 0, 0, 515, 516, 1, 0, 0, 0, 516, 517, 6, 13, 8, 0, 517, 43, 1, 0, 0, 0, 518, 519, 5, 114, 0, 0, 519, 520, 5, 101, 0, 0, 520, 521, 5, 110, 0, 0, 521, 522, 5, 97, 0, 0, 522, 523, 5, 109, 0, 0, 523, 524, 5, 101, 0, 0, 524, 525, 1, 0, 0, 0, 525, 526, 6, 14, 9, 0, 526, 45, 1, 0, 0, 0, 527, 528, 5, 114, 0, 0, 528, 529, 5, 111, 0, 0, 529, 530, 5, 119, 0, 0, 530, 531, 1, 0, 0, 0, 531, 532, 6, 15, 0, 0, 532, 47, 1, 0, 0, 0, 533, 534, 5, 115, 0, 0, 534, 535, 5, 104, 0, 0, 535, 536, 5, 111, 0, 0, 536, 537, 5, 119, 0, 0, 537, 538, 1, 0, 0, 0, 538, 539, 6, 16, 10, 0, 539, 49, 1, 0, 0, 0, 540, 541, 5, 115, 0, 0, 541, 542, 5, 111, 0, 0, 542, 543, 5, 114, 0, 0, 543, 544, 5, 116, 0, 0, 544, 545, 1, 0, 0, 0, 545, 546, 6, 17, 0, 0, 546, 51, 1, 0, 0, 0, 547, 548, 5, 115, 0, 0, 548, 549, 5, 116, 0, 0, 549, 550, 5, 97, 0, 0, 550, 551, 5, 116, 0, 0, 551, 552, 5, 115, 0, 0, 552, 553, 1, 0, 0, 0, 553, 554, 6, 18, 0, 0, 554, 53, 1, 0, 0, 0, 555, 556, 5, 119, 0, 0, 556, 557, 5, 104, 0, 0, 557, 558, 5, 101, 0, 0, 558, 559, 5, 114, 0, 0, 559, 560, 5, 101, 0, 0, 560, 561, 1, 0, 0, 0, 561, 562, 6, 19, 0, 0, 562, 55, 1, 0, 0, 0, 563, 565, 8, 0, 0, 0, 564, 563, 1, 0, 0, 0, 565, 566, 1, 0, 0, 0, 566, 564, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 569, 6, 20, 0, 0, 569, 57, 1, 0, 0, 0, 570, 571, 5, 47, 0, 0, 571, 572, 5, 47, 0, 0, 572, 576, 1, 0, 0, 0, 573, 575, 8, 1, 0, 0, 574, 573, 1, 0, 0, 0, 575, 578, 1, 0, 0, 0, 576, 574, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 580, 1, 0, 0, 0, 578, 576, 1, 0, 0, 0, 579, 581, 5, 13, 0, 0, 580, 579, 1, 0, 0, 0, 580, 581, 1, 0, 0, 0, 581, 583, 1, 0, 0, 0, 582, 584, 5, 10, 0, 0, 583, 582, 1, 0, 0, 0, 583, 584, 1, 0, 0, 0, 584, 585, 1, 0, 0, 0, 585, 586, 6, 21, 11, 0, 586, 59, 1, 0, 0, 0, 587, 588, 5, 47, 0, 0, 588, 589, 5, 42, 0, 0, 589, 594, 1, 0, 0, 0, 590, 593, 3, 60, 22, 0, 591, 593, 9, 0, 0, 0, 592, 590, 1, 0, 0, 0, 592, 591, 1, 0, 0, 0, 593, 596, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 594, 592, 1, 0, 0, 0, 595, 597, 1, 0, 0, 0, 596, 594, 1, 0, 0, 0, 597, 598, 5, 42, 0, 0, 598, 599, 5, 47, 0, 0, 599, 600, 1, 0, 0, 0, 600, 601, 6, 22, 11, 0, 601, 61, 1, 0, 0, 0, 602, 604, 7, 2, 0, 0, 603, 602, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 603, 1, 0, 0, 0, 605, 606, 1, 0, 0, 0, 606, 607, 1, 0, 0, 0, 607, 608, 6, 23, 11, 0, 608, 63, 1, 0, 0, 0, 609, 613, 8, 3, 0, 0, 610, 611, 5, 47, 0, 0, 611, 613, 8, 4, 0, 0, 612, 609, 1, 0, 0, 0, 612, 610, 1, 0, 0, 0, 613, 65, 1, 0, 0, 0, 614, 616, 3, 64, 24, 0, 615, 614, 1, 0, 0, 0, 616, 617, 1, 0, 0, 0, 617, 615, 1, 0, 0, 0, 617, 618, 1, 0, 0, 0, 618, 67, 1, 0, 0, 0, 619, 620, 3, 176, 80, 0, 620, 621, 1, 0, 0, 0, 621, 622, 6, 26, 12, 0, 622, 623, 6, 26, 13, 0, 623, 69, 1, 0, 0, 0, 624, 625, 3, 78, 31, 0, 625, 626, 1, 0, 0, 0, 626, 627, 6, 27, 14, 0, 627, 628, 6, 27, 15, 0, 628, 71, 1, 0, 0, 0, 629, 630, 3, 62, 23, 0, 630, 631, 1, 0, 0, 0, 631, 632, 6, 28, 11, 0, 632, 73, 1, 0, 0, 0, 633, 634, 3, 58, 21, 0, 634, 635, 1, 0, 0, 0, 635, 636, 6, 29, 11, 0, 636, 75, 1, 0, 0, 0, 637, 638, 3, 60, 22, 0, 638, 639, 1, 0, 0, 0, 639, 640, 6, 30, 11, 0, 640, 77, 1, 0, 0, 0, 641, 642, 5, 124, 0, 0, 642, 643, 1, 0, 0, 0, 643, 644, 6, 31, 15, 0, 644, 79, 1, 0, 0, 0, 645, 646, 7, 5, 0, 0, 646, 81, 1, 0, 0, 0, 647, 648, 7, 6, 0, 0, 648, 83, 1, 0, 0, 0, 649, 650, 5, 92, 0, 0, 650, 651, 7, 7, 0, 0, 651, 85, 1, 0, 0, 0, 652, 653, 8, 8, 0, 0, 653, 87, 1, 0, 0, 0, 654, 656, 7, 9, 0, 0, 655, 657, 7, 10, 0, 0, 656, 655, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 659, 1, 0, 0, 0, 658, 660, 3, 80, 32, 0, 659, 658, 1, 0, 0, 0, 660, 661, 1, 0, 0, 0, 661, 659, 1, 0, 0, 0, 661, 662, 1, 0, 0, 0, 662, 89, 1, 0, 0, 0, 663, 664, 5, 64, 0, 0, 664, 91, 1, 0, 0, 0, 665, 666, 5, 96, 0, 0, 666, 93, 1, 0, 0, 0, 667, 671, 8, 11, 0, 0, 668, 669, 5, 96, 0, 0, 669, 671, 5, 96, 0, 0, 670, 667, 1, 0, 0, 0, 670, 668, 1, 0, 0, 0, 671, 95, 1, 0, 0, 0, 672, 673, 5, 95, 0, 0, 673, 97, 1, 0, 0, 0, 674, 678, 3, 82, 33, 0, 675, 678, 3, 80, 32, 0, 676, 678, 3, 96, 40, 0, 677, 674, 1, 0, 0, 0, 677, 675, 1, 0, 0, 0, 677, 676, 1, 0, 0, 0, 678, 99, 1, 0, 0, 0, 679, 684, 5, 34, 0, 0, 680, 683, 3, 84, 34, 0, 681, 683, 3, 86, 35, 0, 682, 680, 1, 0, 0, 0, 682, 681, 1, 0, 0, 0, 683, 686, 1, 0, 0, 0, 684, 682, 1, 0, 0, 0, 684, 685, 1, 0, 0, 0, 685, 687, 1, 0, 0, 0, 686, 684, 1, 0, 0, 0, 687, 709, 5, 34, 0, 0, 688, 689, 5, 34, 0, 0, 689, 690, 5, 34, 0, 0, 690, 691, 5, 34, 0, 0, 691, 695, 1, 0, 0, 0, 692, 694, 8, 1, 0, 0, 693, 692, 1, 0, 0, 0, 694, 697, 1, 0, 0, 0, 695, 696, 1, 0, 0, 0, 695, 693, 1, 0, 0, 0, 696, 698, 1, 0, 0, 0, 697, 695, 1, 0, 0, 0, 698, 699, 5, 34, 0, 0, 699, 700, 5, 34, 0, 0, 700, 701, 5, 34, 0, 0, 701, 703, 1, 0, 0, 0, 702, 704, 5, 34, 0, 0, 703, 702, 1, 0, 0, 0, 703, 704, 1, 0, 0, 0, 704, 706, 1, 0, 0, 0, 705, 707, 5, 34, 0, 0, 706, 705, 1, 0, 0, 0, 706, 707, 1, 0, 0, 0, 707, 709, 1, 0, 0, 0, 708, 679, 1, 0, 0, 0, 708, 688, 1, 0, 0, 0, 709, 101, 1, 0, 0, 0, 710, 712, 3, 80, 32, 0, 711, 710, 1, 0, 0, 0, 712, 713, 1, 0, 0, 0, 713, 711, 1, 0, 0, 0, 713, 714, 1, 0, 0, 0, 714, 103, 1, 0, 0, 0, 715, 717, 3, 80, 32, 0, 716, 715, 1, 0, 0, 0, 717, 718, 1, 0, 0, 0, 718, 716, 1, 0, 0, 0, 718, 719, 1, 0, 0, 0, 719, 720, 1, 0, 0, 0, 720, 724, 3, 120, 52, 0, 721, 723, 3, 80, 32, 0, 722, 721, 1, 0, 0, 0, 723, 726, 1, 0, 0, 0, 724, 722, 1, 0, 0, 0, 724, 725, 1, 0, 0, 0, 725, 758, 1, 0, 0, 0, 726, 724, 1, 0, 0, 0, 727, 729, 3, 120, 52, 0, 728, 730, 3, 80, 32, 0, 729, 728, 1, 0, 0, 0, 730, 731, 1, 0, 0, 0, 731, 729, 1, 0, 0, 0, 731, 732, 1, 0, 0, 0, 732, 758, 1, 0, 0, 0, 733, 735, 3, 80, 32, 0, 734, 733, 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 734, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 745, 1, 0, 0, 0, 738, 742, 3, 120, 52, 0, 739, 741, 3, 80, 32, 0, 740, 739, 1, 0, 0, 0, 741, 744, 1, 0, 0, 0, 742, 740, 1, 0, 0, 0, 742, 743, 1, 0, 0, 0, 743, 746, 1, 0, 0, 0, 744, 742, 1, 0, 0, 0, 745, 738, 1, 0, 0, 0, 745, 746, 1, 0, 0, 0, 746, 747, 1, 0, 0, 0, 747, 748, 3, 88, 36, 0, 748, 758, 1, 0, 0, 0, 749, 751, 3, 120, 52, 0, 750, 752, 3, 80, 32, 0, 751, 750, 1, 0, 0, 0, 752, 753, 1, 0, 0, 0, 753, 751, 1, 0, 0, 0, 753, 754, 1, 0, 0, 0, 754, 755, 1, 0, 0, 0, 755, 756, 3, 88, 36, 0, 756, 758, 1, 0, 0, 0, 757, 716, 1, 0, 0, 0, 757, 727, 1, 0, 0, 0, 757, 734, 1, 0, 0, 0, 757, 749, 1, 0, 0, 0, 758, 105, 1, 0, 0, 0, 759, 760, 5, 98, 0, 0, 760, 761, 5, 121, 0, 0, 761, 107, 1, 0, 0, 0, 762, 763, 5, 97, 0, 0, 763, 764, 5, 110, 0, 0, 764, 765, 5, 100, 0, 0, 765, 109, 1, 0, 0, 0, 766, 767, 5, 97, 0, 0, 767, 768, 5, 115, 0, 0, 768, 769, 5, 99, 0, 0, 769, 111, 1, 0, 0, 0, 770, 771, 5, 61, 0, 0, 771, 113, 1, 0, 0, 0, 772, 773, 5, 58, 0, 0, 773, 774, 5, 58, 0, 0, 774, 115, 1, 0, 0, 0, 775, 776, 5, 44, 0, 0, 776, 117, 1, 0, 0, 0, 777, 778, 5, 100, 0, 0, 778, 779, 5, 101, 0, 0, 779, 780, 5, 115, 0, 0, 780, 781, 5, 99, 0, 0, 781, 119, 1, 0, 0, 0, 782, 783, 5, 46, 0, 0, 783, 121, 1, 0, 0, 0, 784, 785, 5, 102, 0, 0, 785, 786, 5, 97, 0, 0, 786, 787, 5, 108, 0, 0, 787, 788, 5, 115, 0, 0, 788, 789, 5, 101, 0, 0, 789, 123, 1, 0, 0, 0, 790, 791, 5, 102, 0, 0, 791, 792, 5, 105, 0, 0, 792, 793, 5, 114, 0, 0, 793, 794, 5, 115, 0, 0, 794, 795, 5, 116, 0, 0, 795, 125, 1, 0, 0, 0, 796, 797, 5, 108, 0, 0, 797, 798, 5, 97, 0, 0, 798, 799, 5, 115, 0, 0, 799, 800, 5, 116, 0, 0, 800, 127, 1, 0, 0, 0, 801, 802, 5, 40, 0, 0, 802, 129, 1, 0, 0, 0, 803, 804, 5, 105, 0, 0, 804, 805, 5, 110, 0, 0, 805, 131, 1, 0, 0, 0, 806, 807, 5, 105, 0, 0, 807, 808, 5, 115, 0, 0, 808, 133, 1, 0, 0, 0, 809, 810, 5, 108, 0, 0, 810, 811, 5, 105, 0, 0, 811, 812, 5, 107, 0, 0, 812, 813, 5, 101, 0, 0, 813, 135, 1, 0, 0, 0, 814, 815, 5, 110, 0, 0, 815, 816, 5, 111, 0, 0, 816, 817, 5, 116, 0, 0, 817, 137, 1, 0, 0, 0, 818, 819, 5, 110, 0, 0, 819, 820, 5, 117, 0, 0, 820, 821, 5, 108, 0, 0, 821, 822, 5, 108, 0, 0, 822, 139, 1, 0, 0, 0, 823, 824, 5, 110, 0, 0, 824, 825, 5, 117, 0, 0, 825, 826, 5, 108, 0, 0, 826, 827, 5, 108, 0, 0, 827, 828, 5, 115, 0, 0, 828, 141, 1, 0, 0, 0, 829, 830, 5, 111, 0, 0, 830, 831, 5, 114, 0, 0, 831, 143, 1, 0, 0, 0, 832, 833, 5, 63, 0, 0, 833, 145, 1, 0, 0, 0, 834, 835, 5, 114, 0, 0, 835, 836, 5, 108, 0, 0, 836, 837, 5, 105, 0, 0, 837, 838, 5, 107, 0, 0, 838, 839, 5, 101, 0, 0, 839, 147, 1, 0, 0, 0, 840, 841, 5, 41, 0, 0, 841, 149, 1, 0, 0, 0, 842, 843, 5, 116, 0, 0, 843, 844, 5, 114, 0, 0, 844, 845, 5, 117, 0, 0, 845, 846, 5, 101, 0, 0, 846, 151, 1, 0, 0, 0, 847, 848, 5, 61, 0, 0, 848, 849, 5, 61, 0, 0, 849, 153, 1, 0, 0, 0, 850, 851, 5, 61, 0, 0, 851, 852, 5, 126, 0, 0, 852, 155, 1, 0, 0, 0, 853, 854, 5, 33, 0, 0, 854, 855, 5, 61, 0, 0, 855, 157, 1, 0, 0, 0, 856, 857, 5, 60, 0, 0, 857, 159, 1, 0, 0, 0, 858, 859, 5, 60, 0, 0, 859, 860, 5, 61, 0, 0, 860, 161, 1, 0, 0, 0, 861, 862, 5, 62, 0, 0, 862, 163, 1, 0, 0, 0, 863, 864, 5, 62, 0, 0, 864, 865, 5, 61, 0, 0, 865, 165, 1, 0, 0, 0, 866, 867, 5, 43, 0, 0, 867, 167, 1, 0, 0, 0, 868, 869, 5, 45, 0, 0, 869, 169, 1, 0, 0, 0, 870, 871, 5, 42, 0, 0, 871, 171, 1, 0, 0, 0, 872, 873, 5, 47, 0, 0, 873, 173, 1, 0, 0, 0, 874, 875, 5, 37, 0, 0, 875, 175, 1, 0, 0, 0, 876, 877, 5, 91, 0, 0, 877, 878, 1, 0, 0, 0, 878, 879, 6, 80, 0, 0, 879, 880, 6, 80, 0, 0, 880, 177, 1, 0, 0, 0, 881, 882, 5, 93, 0, 0, 882, 883, 1, 0, 0, 0, 883, 884, 6, 81, 15, 0, 884, 885, 6, 81, 15, 0, 885, 179, 1, 0, 0, 0, 886, 890, 3, 82, 33, 0, 887, 889, 3, 98, 41, 0, 888, 887, 1, 0, 0, 0, 889, 892, 1, 0, 0, 0, 890, 888, 1, 0, 0, 0, 890, 891, 1, 0, 0, 0, 891, 903, 1, 0, 0, 0, 892, 890, 1, 0, 0, 0, 893, 896, 3, 96, 40, 0, 894, 896, 3, 90, 37, 0, 895, 893, 1, 0, 0, 0, 895, 894, 1, 0, 0, 0, 896, 898, 1, 0, 0, 0, 897, 899, 3, 98, 41, 0, 898, 897, 1, 0, 0, 0, 899, 900, 1, 0, 0, 0, 900, 898, 1, 0, 0, 0, 900, 901, 1, 0, 0, 0, 901, 903, 1, 0, 0, 0, 902, 886, 1, 0, 0, 0, 902, 895, 1, 0, 0, 0, 903, 181, 1, 0, 0, 0, 904, 906, 3, 92, 38, 0, 905, 907, 3, 94, 39, 0, 906, 905, 1, 0, 0, 0, 907, 908, 1, 0, 0, 0, 908, 906, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 3, 92, 38, 0, 911, 183, 1, 0, 0, 0, 912, 913, 3, 182, 83, 0, 913, 185, 1, 0, 0, 0, 914, 915, 3, 58, 21, 0, 915, 916, 1, 0, 0, 0, 916, 917, 6, 85, 11, 0, 917, 187, 1, 0, 0, 0, 918, 919, 3, 60, 22, 0, 919, 920, 1, 0, 0, 0, 920, 921, 6, 86, 11, 0, 921, 189, 1, 0, 0, 0, 922, 923, 3, 62, 23, 0, 923, 924, 1, 0, 0, 0, 924, 925, 6, 87, 11, 0, 925, 191, 1, 0, 0, 0, 926, 927, 3, 78, 31, 0, 927, 928, 1, 0, 0, 0, 928, 929, 6, 88, 14, 0, 929, 930, 6, 88, 15, 0, 930, 193, 1, 0, 0, 0, 931, 932, 3, 176, 80, 0, 932, 933, 1, 0, 0, 0, 933, 934, 6, 89, 12, 0, 934, 195, 1, 0, 0, 0, 935, 936, 3, 178, 81, 0, 936, 937, 1, 0, 0, 0, 937, 938, 6, 90, 16, 0, 938, 197, 1, 0, 0, 0, 939, 940, 3, 116, 50, 0, 940, 941, 1, 0, 0, 0, 941, 942, 6, 91, 17, 0, 942, 199, 1, 0, 0, 0, 943, 944, 3, 112, 48, 0, 944, 945, 1, 0, 0, 0, 945, 946, 6, 92, 18, 0, 946, 201, 1, 0, 0, 0, 947, 948, 3, 100, 42, 0, 948, 949, 1, 0, 0, 0, 949, 950, 6, 93, 19, 0, 950, 203, 1, 0, 0, 0, 951, 952, 5, 109, 0, 0, 952, 953, 5, 101, 0, 0, 953, 954, 5, 116, 0, 0, 954, 955, 5, 97, 0, 0, 955, 956, 5, 100, 0, 0, 956, 957, 5, 97, 0, 0, 957, 958, 5, 116, 0, 0, 958, 959, 5, 97, 0, 0, 959, 205, 1, 0, 0, 0, 960, 961, 3, 66, 25, 0, 961, 962, 1, 0, 0, 0, 962, 963, 6, 95, 20, 0, 963, 207, 1, 0, 0, 0, 964, 965, 3, 58, 21, 0, 965, 966, 1, 0, 0, 0, 966, 967, 6, 96, 11, 0, 967, 209, 1, 0, 0, 0, 968, 969, 3, 60, 22, 0, 969, 970, 1, 0, 0, 0, 970, 971, 6, 97, 11, 0, 971, 211, 1, 0, 0, 0, 972, 973, 3, 62, 23, 0, 973, 974, 1, 0, 0, 0, 974, 975, 6, 98, 11, 0, 975, 213, 1, 0, 0, 0, 976, 977, 3, 78, 31, 0, 977, 978, 1, 0, 0, 0, 978, 979, 6, 99, 14, 0, 979, 980, 6, 99, 15, 0, 980, 215, 1, 0, 0, 0, 981, 982, 3, 120, 52, 0, 982, 983, 1, 0, 0, 0, 983, 984, 6, 100, 21, 0, 984, 217, 1, 0, 0, 0, 985, 986, 3, 116, 50, 0, 986, 987, 1, 0, 0, 0, 987, 988, 6, 101, 17, 0, 988, 219, 1, 0, 0, 0, 989, 994, 3, 82, 33, 0, 990, 994, 3, 80, 32, 0, 991, 994, 3, 96, 40, 0, 992, 994, 3, 170, 77, 0, 993, 989, 1, 0, 0, 0, 993, 990, 1, 0, 0, 0, 993, 991, 1, 0, 0, 0, 993, 992, 1, 0, 0, 0, 994, 221, 1, 0, 0, 0, 995, 998, 3, 82, 33, 0, 996, 998, 3, 170, 77, 0, 997, 995, 1, 0, 0, 0, 997, 996, 1, 0, 0, 0, 998, 1002, 1, 0, 0, 0, 999, 1001, 3, 220, 102, 0, 1000, 999, 1, 0, 0, 0, 1001, 1004, 1, 0, 0, 0, 1002, 1000, 1, 0, 0, 0, 1002, 1003, 1, 0, 0, 0, 1003, 1015, 1, 0, 0, 0, 1004, 1002, 1, 0, 0, 0, 1005, 1008, 3, 96, 40, 0, 1006, 1008, 3, 90, 37, 0, 1007, 1005, 1, 0, 0, 0, 1007, 1006, 1, 0, 0, 0, 1008, 1010, 1, 0, 0, 0, 1009, 1011, 3, 220, 102, 0, 1010, 1009, 1, 0, 0, 0, 1011, 1012, 1, 0, 0, 0, 1012, 1010, 1, 0, 0, 0, 1012, 1013, 1, 0, 0, 0, 1013, 1015, 1, 0, 0, 0, 1014, 997, 1, 0, 0, 0, 1014, 1007, 1, 0, 0, 0, 1015, 223, 1, 0, 0, 0, 1016, 1019, 3, 222, 103, 0, 1017, 1019, 3, 182, 83, 0, 1018, 1016, 1, 0, 0, 0, 1018, 1017, 1, 0, 0, 0, 1019, 1020, 1, 0, 0, 0, 1020, 1018, 1, 0, 0, 0, 1020, 1021, 1, 0, 0, 0, 1021, 225, 1, 0, 0, 0, 1022, 1023, 3, 58, 21, 0, 1023, 1024, 1, 0, 0, 0, 1024, 1025, 6, 105, 11, 0, 1025, 227, 1, 0, 0, 0, 1026, 1027, 3, 60, 22, 0, 1027, 1028, 1, 0, 0, 0, 1028, 1029, 6, 106, 11, 0, 1029, 229, 1, 0, 0, 0, 1030, 1031, 3, 62, 23, 0, 1031, 1032, 1, 0, 0, 0, 1032, 1033, 6, 107, 11, 0, 1033, 231, 1, 0, 0, 0, 1034, 1035, 3, 78, 31, 0, 1035, 1036, 1, 0, 0, 0, 1036, 1037, 6, 108, 14, 0, 1037, 1038, 6, 108, 15, 0, 1038, 233, 1, 0, 0, 0, 1039, 1040, 3, 112, 48, 0, 1040, 1041, 1, 0, 0, 0, 1041, 1042, 6, 109, 18, 0, 1042, 235, 1, 0, 0, 0, 1043, 1044, 3, 116, 50, 0, 1044, 1045, 1, 0, 0, 0, 1045, 1046, 6, 110, 17, 0, 1046, 237, 1, 0, 0, 0, 1047, 1048, 3, 120, 52, 0, 1048, 1049, 1, 0, 0, 0, 1049, 1050, 6, 111, 21, 0, 1050, 239, 1, 0, 0, 0, 1051, 1052, 5, 97, 0, 0, 1052, 1053, 5, 115, 0, 0, 1053, 241, 1, 0, 0, 0, 1054, 1055, 3, 224, 104, 0, 1055, 1056, 1, 0, 0, 0, 1056, 1057, 6, 113, 22, 0, 1057, 243, 1, 0, 0, 0, 1058, 1059, 3, 58, 21, 0, 1059, 1060, 1, 0, 0, 0, 1060, 1061, 6, 114, 11, 0, 1061, 245, 1, 0, 0, 0, 1062, 1063, 3, 60, 22, 0, 1063, 1064, 1, 0, 0, 0, 1064, 1065, 6, 115, 11, 0, 1065, 247, 1, 0, 0, 0, 1066, 1067, 3, 62, 23, 0, 1067, 1068, 1, 0, 0, 0, 1068, 1069, 6, 116, 11, 0, 1069, 249, 1, 0, 0, 0, 1070, 1071, 3, 78, 31, 0, 1071, 1072, 1, 0, 0, 0, 1072, 1073, 6, 117, 14, 0, 1073, 1074, 6, 117, 15, 0, 1074, 251, 1, 0, 0, 0, 1075, 1076, 3, 176, 80, 0, 1076, 1077, 1, 0, 0, 0, 1077, 1078, 6, 118, 12, 0, 1078, 1079, 6, 118, 23, 0, 1079, 253, 1, 0, 0, 0, 1080, 1081, 5, 111, 0, 0, 1081, 1082, 5, 110, 0, 0, 1082, 1083, 1, 0, 0, 0, 1083, 1084, 6, 119, 24, 0, 1084, 255, 1, 0, 0, 0, 1085, 1086, 5, 119, 0, 0, 1086, 1087, 5, 105, 0, 0, 1087, 1088, 5, 116, 0, 0, 1088, 1089, 5, 104, 0, 0, 1089, 1090, 1, 0, 0, 0, 1090, 1091, 6, 120, 24, 0, 1091, 257, 1, 0, 0, 0, 1092, 1093, 8, 12, 0, 0, 1093, 259, 1, 0, 0, 0, 1094, 1096, 3, 258, 121, 0, 1095, 1094, 1, 0, 0, 0, 1096, 1097, 1, 0, 0, 0, 1097, 1095, 1, 0, 0, 0, 1097, 1098, 1, 0, 0, 0, 1098, 1099, 1, 0, 0, 0, 1099, 1100, 3, 358, 171, 0, 1100, 1102, 1, 0, 0, 0, 1101, 1095, 1, 0, 0, 0, 1101, 1102, 1, 0, 0, 0, 1102, 1104, 1, 0, 0, 0, 1103, 1105, 3, 258, 121, 0, 1104, 1103, 1, 0, 0, 0, 1105, 1106, 1, 0, 0, 0, 1106, 1104, 1, 0, 0, 0, 1106, 1107, 1, 0, 0, 0, 1107, 261, 1, 0, 0, 0, 1108, 1109, 3, 184, 84, 0, 1109, 1110, 1, 0, 0, 0, 1110, 1111, 6, 123, 25, 0, 1111, 263, 1, 0, 0, 0, 1112, 1113, 3, 260, 122, 0, 1113, 1114, 1, 0, 0, 0, 1114, 1115, 6, 124, 26, 0, 1115, 265, 1, 0, 0, 0, 1116, 1117, 3, 58, 21, 0, 1117, 1118, 1, 0, 0, 0, 1118, 1119, 6, 125, 11, 0, 1119, 267, 1, 0, 0, 0, 1120, 1121, 3, 60, 22, 0, 1121, 1122, 1, 0, 0, 0, 1122, 1123, 6, 126, 11, 0, 1123, 269, 1, 0, 0, 0, 1124, 1125, 3, 62, 23, 0, 1125, 1126, 1, 0, 0, 0, 1126, 1127, 6, 127, 11, 0, 1127, 271, 1, 0, 0, 0, 1128, 1129, 3, 78, 31, 0, 1129, 1130, 1, 0, 0, 0, 1130, 1131, 6, 128, 14, 0, 1131, 1132, 6, 128, 15, 0, 1132, 1133, 6, 128, 15, 0, 1133, 273, 1, 0, 0, 0, 1134, 1135, 3, 112, 48, 0, 1135, 1136, 1, 0, 0, 0, 1136, 1137, 6, 129, 18, 0, 1137, 275, 1, 0, 0, 0, 1138, 1139, 3, 116, 50, 0, 1139, 1140, 1, 0, 0, 0, 1140, 1141, 6, 130, 17, 0, 1141, 277, 1, 0, 0, 0, 1142, 1143, 3, 120, 52, 0, 1143, 1144, 1, 0, 0, 0, 1144, 1145, 6, 131, 21, 0, 1145, 279, 1, 0, 0, 0, 1146, 1147, 3, 256, 120, 0, 1147, 1148, 1, 0, 0, 0, 1148, 1149, 6, 132, 27, 0, 1149, 281, 1, 0, 0, 0, 1150, 1151, 3, 224, 104, 0, 1151, 1152, 1, 0, 0, 0, 1152, 1153, 6, 133, 22, 0, 1153, 283, 1, 0, 0, 0, 1154, 1155, 3, 184, 84, 0, 1155, 1156, 1, 0, 0, 0, 1156, 1157, 6, 134, 25, 0, 1157, 285, 1, 0, 0, 0, 1158, 1159, 3, 58, 21, 0, 1159, 1160, 1, 0, 0, 0, 1160, 1161, 6, 135, 11, 0, 1161, 287, 1, 0, 0, 0, 1162, 1163, 3, 60, 22, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 6, 136, 11, 0, 1165, 289, 1, 0, 0, 0, 1166, 1167, 3, 62, 23, 0, 1167, 1168, 1, 0, 0, 0, 1168, 1169, 6, 137, 11, 0, 1169, 291, 1, 0, 0, 0, 1170, 1171, 3, 78, 31, 0, 1171, 1172, 1, 0, 0, 0, 1172, 1173, 6, 138, 14, 0, 1173, 1174, 6, 138, 15, 0, 1174, 293, 1, 0, 0, 0, 1175, 1176, 3, 116, 50, 0, 1176, 1177, 1, 0, 0, 0, 1177, 1178, 6, 139, 17, 0, 1178, 295, 1, 0, 0, 0, 1179, 1180, 3, 120, 52, 0, 1180, 1181, 1, 0, 0, 0, 1181, 1182, 6, 140, 21, 0, 1182, 297, 1, 0, 0, 0, 1183, 1184, 3, 254, 119, 0, 1184, 1185, 1, 0, 0, 0, 1185, 1186, 6, 141, 28, 0, 1186, 1187, 6, 141, 29, 0, 1187, 299, 1, 0, 0, 0, 1188, 1189, 3, 66, 25, 0, 1189, 1190, 1, 0, 0, 0, 1190, 1191, 6, 142, 20, 0, 1191, 301, 1, 0, 0, 0, 1192, 1193, 3, 58, 21, 0, 1193, 1194, 1, 0, 0, 0, 1194, 1195, 6, 143, 11, 0, 1195, 303, 1, 0, 0, 0, 1196, 1197, 3, 60, 22, 0, 1197, 1198, 1, 0, 0, 0, 1198, 1199, 6, 144, 11, 0, 1199, 305, 1, 0, 0, 0, 1200, 1201, 3, 62, 23, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 6, 145, 11, 0, 1203, 307, 1, 0, 0, 0, 1204, 1205, 3, 78, 31, 0, 1205, 1206, 1, 0, 0, 0, 1206, 1207, 6, 146, 14, 0, 1207, 1208, 6, 146, 15, 0, 1208, 1209, 6, 146, 15, 0, 1209, 309, 1, 0, 0, 0, 1210, 1211, 3, 116, 50, 0, 1211, 1212, 1, 0, 0, 0, 1212, 1213, 6, 147, 17, 0, 1213, 311, 1, 0, 0, 0, 1214, 1215, 3, 120, 52, 0, 1215, 1216, 1, 0, 0, 0, 1216, 1217, 6, 148, 21, 0, 1217, 313, 1, 0, 0, 0, 1218, 1219, 3, 224, 104, 0, 1219, 1220, 1, 0, 0, 0, 1220, 1221, 6, 149, 22, 0, 1221, 315, 1, 0, 0, 0, 1222, 1223, 3, 58, 21, 0, 1223, 1224, 1, 0, 0, 0, 1224, 1225, 6, 150, 11, 0, 1225, 317, 1, 0, 0, 0, 1226, 1227, 3, 60, 22, 0, 1227, 1228, 1, 0, 0, 0, 1228, 1229, 6, 151, 11, 0, 1229, 319, 1, 0, 0, 0, 1230, 1231, 3, 62, 23, 0, 1231, 1232, 1, 0, 0, 0, 1232, 1233, 6, 152, 11, 0, 1233, 321, 1, 0, 0, 0, 1234, 1235, 3, 78, 31, 0, 1235, 1236, 1, 0, 0, 0, 1236, 1237, 6, 153, 14, 0, 1237, 1238, 6, 153, 15, 0, 1238, 323, 1, 0, 0, 0, 1239, 1240, 3, 120, 52, 0, 1240, 1241, 1, 0, 0, 0, 1241, 1242, 6, 154, 21, 0, 1242, 325, 1, 0, 0, 0, 1243, 1244, 3, 184, 84, 0, 1244, 1245, 1, 0, 0, 0, 1245, 1246, 6, 155, 25, 0, 1246, 327, 1, 0, 0, 0, 1247, 1248, 3, 180, 82, 0, 1248, 1249, 1, 0, 0, 0, 1249, 1250, 6, 156, 30, 0, 1250, 329, 1, 0, 0, 0, 1251, 1252, 3, 58, 21, 0, 1252, 1253, 1, 0, 0, 0, 1253, 1254, 6, 157, 11, 0, 1254, 331, 1, 0, 0, 0, 1255, 1256, 3, 60, 22, 0, 1256, 1257, 1, 0, 0, 0, 1257, 1258, 6, 158, 11, 0, 1258, 333, 1, 0, 0, 0, 1259, 1260, 3, 62, 23, 0, 1260, 1261, 1, 0, 0, 0, 1261, 1262, 6, 159, 11, 0, 1262, 335, 1, 0, 0, 0, 1263, 1264, 3, 78, 31, 0, 1264, 1265, 1, 0, 0, 0, 1265, 1266, 6, 160, 14, 0, 1266, 1267, 6, 160, 15, 0, 1267, 337, 1, 0, 0, 0, 1268, 1269, 5, 105, 0, 0, 1269, 1270, 5, 110, 0, 0, 1270, 1271, 5, 102, 0, 0, 1271, 1272, 5, 111, 0, 0, 1272, 339, 1, 0, 0, 0, 1273, 1274, 3, 58, 21, 0, 1274, 1275, 1, 0, 0, 0, 1275, 1276, 6, 162, 11, 0, 1276, 341, 1, 0, 0, 0, 1277, 1278, 3, 60, 22, 0, 1278, 1279, 1, 0, 0, 0, 1279, 1280, 6, 163, 11, 0, 1280, 343, 1, 0, 0, 0, 1281, 1282, 3, 62, 23, 0, 1282, 1283, 1, 0, 0, 0, 1283, 1284, 6, 164, 11, 0, 1284, 345, 1, 0, 0, 0, 1285, 1286, 3, 78, 31, 0, 1286, 1287, 1, 0, 0, 0, 1287, 1288, 6, 165, 14, 0, 1288, 1289, 6, 165, 15, 0, 1289, 347, 1, 0, 0, 0, 1290, 1291, 5, 102, 0, 0, 1291, 1292, 5, 117, 0, 0, 1292, 1293, 5, 110, 0, 0, 1293, 1294, 5, 99, 0, 0, 1294, 1295, 5, 116, 0, 0, 1295, 1296, 5, 105, 0, 0, 1296, 1297, 5, 111, 0, 0, 1297, 1298, 5, 110, 0, 0, 1298, 1299, 5, 115, 0, 0, 1299, 349, 1, 0, 0, 0, 1300, 1301, 3, 58, 21, 0, 1301, 1302, 1, 0, 0, 0, 1302, 1303, 6, 167, 11, 0, 1303, 351, 1, 0, 0, 0, 1304, 1305, 3, 60, 22, 0, 1305, 1306, 1, 0, 0, 0, 1306, 1307, 6, 168, 11, 0, 1307, 353, 1, 0, 0, 0, 1308, 1309, 3, 62, 23, 0, 1309, 1310, 1, 0, 0, 0, 1310, 1311, 6, 169, 11, 0, 1311, 355, 1, 0, 0, 0, 1312, 1313, 3, 178, 81, 0, 1313, 1314, 1, 0, 0, 0, 1314, 1315, 6, 170, 16, 0, 1315, 1316, 6, 170, 15, 0, 1316, 357, 1, 0, 0, 0, 1317, 1318, 5, 58, 0, 0, 1318, 359, 1, 0, 0, 0, 1319, 1325, 3, 90, 37, 0, 1320, 1325, 3, 80, 32, 0, 1321, 1325, 3, 120, 52, 0, 1322, 1325, 3, 82, 33, 0, 1323, 1325, 3, 96, 40, 0, 1324, 1319, 1, 0, 0, 0, 1324, 1320, 1, 0, 0, 0, 1324, 1321, 1, 0, 0, 0, 1324, 1322, 1, 0, 0, 0, 1324, 1323, 1, 0, 0, 0, 1325, 1326, 1, 0, 0, 0, 1326, 1324, 1, 0, 0, 0, 1326, 1327, 1, 0, 0, 0, 1327, 361, 1, 0, 0, 0, 1328, 1329, 3, 58, 21, 0, 1329, 1330, 1, 0, 0, 0, 1330, 1331, 6, 173, 11, 0, 1331, 363, 1, 0, 0, 0, 1332, 1333, 3, 60, 22, 0, 1333, 1334, 1, 0, 0, 0, 1334, 1335, 6, 174, 11, 0, 1335, 365, 1, 0, 0, 0, 1336, 1337, 3, 62, 23, 0, 1337, 1338, 1, 0, 0, 0, 1338, 1339, 6, 175, 11, 0, 1339, 367, 1, 0, 0, 0, 1340, 1341, 3, 78, 31, 0, 1341, 1342, 1, 0, 0, 0, 1342, 1343, 6, 176, 14, 0, 1343, 1344, 6, 176, 15, 0, 1344, 369, 1, 0, 0, 0, 1345, 1346, 3, 66, 25, 0, 1346, 1347, 1, 0, 0, 0, 1347, 1348, 6, 177, 20, 0, 1348, 1349, 6, 177, 15, 0, 1349, 1350, 6, 177, 31, 0, 1350, 371, 1, 0, 0, 0, 1351, 1352, 3, 58, 21, 0, 1352, 1353, 1, 0, 0, 0, 1353, 1354, 6, 178, 11, 0, 1354, 373, 1, 0, 0, 0, 1355, 1356, 3, 60, 22, 0, 1356, 1357, 1, 0, 0, 0, 1357, 1358, 6, 179, 11, 0, 1358, 375, 1, 0, 0, 0, 1359, 1360, 3, 62, 23, 0, 1360, 1361, 1, 0, 0, 0, 1361, 1362, 6, 180, 11, 0, 1362, 377, 1, 0, 0, 0, 1363, 1364, 3, 116, 50, 0, 1364, 1365, 1, 0, 0, 0, 1365, 1366, 6, 181, 17, 0, 1366, 1367, 6, 181, 15, 0, 1367, 1368, 6, 181, 7, 0, 1368, 379, 1, 0, 0, 0, 1369, 1370, 3, 58, 21, 0, 1370, 1371, 1, 0, 0, 0, 1371, 1372, 6, 182, 11, 0, 1372, 381, 1, 0, 0, 0, 1373, 1374, 3, 60, 22, 0, 1374, 1375, 1, 0, 0, 0, 1375, 1376, 6, 183, 11, 0, 1376, 383, 1, 0, 0, 0, 1377, 1378, 3, 62, 23, 0, 1378, 1379, 1, 0, 0, 0, 1379, 1380, 6, 184, 11, 0, 1380, 385, 1, 0, 0, 0, 1381, 1382, 3, 184, 84, 0, 1382, 1383, 1, 0, 0, 0, 1383, 1384, 6, 185, 15, 0, 1384, 1385, 6, 185, 0, 0, 1385, 1386, 6, 185, 25, 0, 1386, 387, 1, 0, 0, 0, 1387, 1388, 3, 180, 82, 0, 1388, 1389, 1, 0, 0, 0, 1389, 1390, 6, 186, 15, 0, 1390, 1391, 6, 186, 0, 0, 1391, 1392, 6, 186, 30, 0, 1392, 389, 1, 0, 0, 0, 1393, 1394, 3, 106, 45, 0, 1394, 1395, 1, 0, 0, 0, 1395, 1396, 6, 187, 15, 0, 1396, 1397, 6, 187, 0, 0, 1397, 1398, 6, 187, 32, 0, 1398, 391, 1, 0, 0, 0, 1399, 1400, 3, 78, 31, 0, 1400, 1401, 1, 0, 0, 0, 1401, 1402, 6, 188, 14, 0, 1402, 1403, 6, 188, 15, 0, 1403, 393, 1, 0, 0, 0, 62, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 566, 576, 580, 583, 592, 594, 605, 612, 617, 656, 661, 670, 677, 682, 684, 695, 703, 706, 708, 713, 718, 724, 731, 736, 742, 745, 753, 757, 890, 895, 900, 902, 908, 993, 997, 1002, 1007, 1012, 1014, 1018, 1020, 1097, 1101, 1106, 1324, 1326, 33, 5, 2, 0, 5, 4, 0, 5, 6, 0, 5, 1, 0, 5, 3, 0, 5, 8, 0, 5, 12, 0, 5, 14, 0, 5, 10, 0, 5, 5, 0, 5, 11, 0, 0, 1, 0, 7, 68, 0, 5, 0, 0, 7, 29, 0, 4, 0, 0, 7, 69, 0, 7, 38, 0, 7, 36, 0, 7, 30, 0, 7, 25, 0, 7, 40, 0, 7, 79, 0, 5, 13, 0, 5, 7, 0, 7, 71, 0, 7, 89, 0, 7, 88, 0, 7, 87, 0, 5, 9, 0, 7, 70, 0, 5, 15, 0, 7, 33, 0] \ No newline at end of file +[4, 0, 124, 1422, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 4, 20, 567, 8, 20, 11, 20, 12, 20, 568, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 577, 8, 21, 10, 21, 12, 21, 580, 9, 21, 1, 21, 3, 21, 583, 8, 21, 1, 21, 3, 21, 586, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 595, 8, 22, 10, 22, 12, 22, 598, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 4, 23, 606, 8, 23, 11, 23, 12, 23, 607, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 3, 24, 615, 8, 24, 1, 25, 4, 25, 618, 8, 25, 11, 25, 12, 25, 619, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 3, 36, 659, 8, 36, 1, 36, 4, 36, 662, 8, 36, 11, 36, 12, 36, 663, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 3, 39, 673, 8, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 3, 41, 680, 8, 41, 1, 42, 1, 42, 1, 42, 5, 42, 685, 8, 42, 10, 42, 12, 42, 688, 9, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 696, 8, 42, 10, 42, 12, 42, 699, 9, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 706, 8, 42, 1, 42, 3, 42, 709, 8, 42, 3, 42, 711, 8, 42, 1, 43, 4, 43, 714, 8, 43, 11, 43, 12, 43, 715, 1, 44, 4, 44, 719, 8, 44, 11, 44, 12, 44, 720, 1, 44, 1, 44, 5, 44, 725, 8, 44, 10, 44, 12, 44, 728, 9, 44, 1, 44, 1, 44, 4, 44, 732, 8, 44, 11, 44, 12, 44, 733, 1, 44, 4, 44, 737, 8, 44, 11, 44, 12, 44, 738, 1, 44, 1, 44, 5, 44, 743, 8, 44, 10, 44, 12, 44, 746, 9, 44, 3, 44, 748, 8, 44, 1, 44, 1, 44, 1, 44, 1, 44, 4, 44, 754, 8, 44, 11, 44, 12, 44, 755, 1, 44, 1, 44, 3, 44, 760, 8, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 5, 80, 882, 8, 80, 10, 80, 12, 80, 885, 9, 80, 1, 80, 1, 80, 4, 80, 889, 8, 80, 11, 80, 12, 80, 890, 3, 80, 893, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 5, 83, 907, 8, 83, 10, 83, 12, 83, 910, 9, 83, 1, 83, 1, 83, 3, 83, 914, 8, 83, 1, 83, 4, 83, 917, 8, 83, 11, 83, 12, 83, 918, 3, 83, 921, 8, 83, 1, 84, 1, 84, 4, 84, 925, 8, 84, 11, 84, 12, 84, 926, 1, 84, 1, 84, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 3, 103, 1012, 8, 103, 1, 104, 1, 104, 3, 104, 1016, 8, 104, 1, 104, 5, 104, 1019, 8, 104, 10, 104, 12, 104, 1022, 9, 104, 1, 104, 1, 104, 3, 104, 1026, 8, 104, 1, 104, 4, 104, 1029, 8, 104, 11, 104, 12, 104, 1030, 3, 104, 1033, 8, 104, 1, 105, 1, 105, 4, 105, 1037, 8, 105, 11, 105, 12, 105, 1038, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1, 108, 1, 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 123, 4, 123, 1114, 8, 123, 11, 123, 12, 123, 1115, 1, 123, 1, 123, 3, 123, 1120, 8, 123, 1, 123, 4, 123, 1123, 8, 123, 11, 123, 12, 123, 1124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 128, 1, 129, 1, 129, 1, 129, 1, 129, 1, 129, 1, 129, 1, 130, 1, 130, 1, 130, 1, 130, 1, 131, 1, 131, 1, 131, 1, 131, 1, 132, 1, 132, 1, 132, 1, 132, 1, 133, 1, 133, 1, 133, 1, 133, 1, 134, 1, 134, 1, 134, 1, 134, 1, 135, 1, 135, 1, 135, 1, 135, 1, 136, 1, 136, 1, 136, 1, 136, 1, 137, 1, 137, 1, 137, 1, 137, 1, 138, 1, 138, 1, 138, 1, 138, 1, 139, 1, 139, 1, 139, 1, 139, 1, 139, 1, 140, 1, 140, 1, 140, 1, 140, 1, 141, 1, 141, 1, 141, 1, 141, 1, 142, 1, 142, 1, 142, 1, 142, 1, 142, 1, 143, 1, 143, 1, 143, 1, 143, 1, 144, 1, 144, 1, 144, 1, 144, 1, 145, 1, 145, 1, 145, 1, 145, 1, 146, 1, 146, 1, 146, 1, 146, 1, 147, 1, 147, 1, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 1, 158, 1, 158, 1, 158, 1, 159, 1, 159, 1, 159, 1, 159, 1, 160, 1, 160, 1, 160, 1, 160, 1, 161, 1, 161, 1, 161, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 171, 1, 172, 1, 172, 1, 173, 1, 173, 1, 173, 1, 173, 1, 173, 4, 173, 1343, 8, 173, 11, 173, 12, 173, 1344, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 177, 1, 178, 1, 178, 1, 178, 1, 178, 1, 178, 1, 178, 1, 179, 1, 179, 1, 179, 1, 179, 1, 180, 1, 180, 1, 180, 1, 180, 1, 181, 1, 181, 1, 181, 1, 181, 1, 182, 1, 182, 1, 182, 1, 182, 1, 182, 1, 182, 1, 183, 1, 183, 1, 183, 1, 183, 1, 184, 1, 184, 1, 184, 1, 184, 1, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 1, 187, 1, 187, 1, 187, 1, 187, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 2, 596, 697, 0, 190, 16, 1, 18, 2, 20, 3, 22, 4, 24, 5, 26, 6, 28, 7, 30, 8, 32, 9, 34, 10, 36, 11, 38, 12, 40, 13, 42, 14, 44, 15, 46, 16, 48, 17, 50, 18, 52, 19, 54, 20, 56, 21, 58, 22, 60, 23, 62, 24, 64, 0, 66, 25, 68, 0, 70, 0, 72, 26, 74, 27, 76, 28, 78, 29, 80, 0, 82, 0, 84, 0, 86, 0, 88, 0, 90, 0, 92, 0, 94, 0, 96, 0, 98, 0, 100, 30, 102, 31, 104, 32, 106, 33, 108, 34, 110, 35, 112, 36, 114, 37, 116, 38, 118, 39, 120, 40, 122, 41, 124, 42, 126, 43, 128, 44, 130, 45, 132, 46, 134, 47, 136, 48, 138, 49, 140, 50, 142, 51, 144, 52, 146, 53, 148, 54, 150, 55, 152, 56, 154, 57, 156, 58, 158, 59, 160, 60, 162, 61, 164, 62, 166, 63, 168, 64, 170, 65, 172, 66, 174, 67, 176, 68, 178, 69, 180, 70, 182, 71, 184, 0, 186, 72, 188, 73, 190, 74, 192, 75, 194, 0, 196, 0, 198, 0, 200, 0, 202, 0, 204, 0, 206, 76, 208, 0, 210, 77, 212, 78, 214, 79, 216, 0, 218, 0, 220, 0, 222, 0, 224, 0, 226, 80, 228, 81, 230, 82, 232, 83, 234, 0, 236, 0, 238, 0, 240, 0, 242, 84, 244, 0, 246, 85, 248, 86, 250, 87, 252, 0, 254, 0, 256, 88, 258, 89, 260, 0, 262, 90, 264, 0, 266, 0, 268, 91, 270, 92, 272, 93, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286, 0, 288, 94, 290, 95, 292, 96, 294, 0, 296, 0, 298, 0, 300, 0, 302, 0, 304, 97, 306, 98, 308, 99, 310, 0, 312, 0, 314, 0, 316, 0, 318, 100, 320, 101, 322, 102, 324, 0, 326, 0, 328, 0, 330, 0, 332, 103, 334, 104, 336, 105, 338, 0, 340, 106, 342, 107, 344, 108, 346, 109, 348, 0, 350, 110, 352, 111, 354, 112, 356, 113, 358, 0, 360, 114, 362, 115, 364, 116, 366, 117, 368, 118, 370, 0, 372, 0, 374, 119, 376, 120, 378, 121, 380, 0, 382, 122, 384, 123, 386, 124, 388, 0, 390, 0, 392, 0, 394, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 13, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 10, 0, 9, 10, 13, 13, 32, 32, 44, 44, 47, 47, 61, 61, 91, 91, 93, 93, 96, 96, 124, 124, 2, 0, 42, 42, 47, 47, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 5, 0, 34, 34, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 1, 0, 96, 96, 11, 0, 9, 10, 13, 13, 32, 32, 34, 35, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1448, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 66, 1, 0, 0, 0, 1, 68, 1, 0, 0, 0, 1, 70, 1, 0, 0, 0, 1, 72, 1, 0, 0, 0, 1, 74, 1, 0, 0, 0, 1, 76, 1, 0, 0, 0, 2, 78, 1, 0, 0, 0, 2, 100, 1, 0, 0, 0, 2, 102, 1, 0, 0, 0, 2, 104, 1, 0, 0, 0, 2, 106, 1, 0, 0, 0, 2, 108, 1, 0, 0, 0, 2, 110, 1, 0, 0, 0, 2, 112, 1, 0, 0, 0, 2, 114, 1, 0, 0, 0, 2, 116, 1, 0, 0, 0, 2, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 124, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 128, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 2, 138, 1, 0, 0, 0, 2, 140, 1, 0, 0, 0, 2, 142, 1, 0, 0, 0, 2, 144, 1, 0, 0, 0, 2, 146, 1, 0, 0, 0, 2, 148, 1, 0, 0, 0, 2, 150, 1, 0, 0, 0, 2, 152, 1, 0, 0, 0, 2, 154, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 2, 158, 1, 0, 0, 0, 2, 160, 1, 0, 0, 0, 2, 162, 1, 0, 0, 0, 2, 164, 1, 0, 0, 0, 2, 166, 1, 0, 0, 0, 2, 168, 1, 0, 0, 0, 2, 170, 1, 0, 0, 0, 2, 172, 1, 0, 0, 0, 2, 174, 1, 0, 0, 0, 2, 176, 1, 0, 0, 0, 2, 178, 1, 0, 0, 0, 2, 180, 1, 0, 0, 0, 2, 182, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 2, 188, 1, 0, 0, 0, 2, 190, 1, 0, 0, 0, 2, 192, 1, 0, 0, 0, 3, 194, 1, 0, 0, 0, 3, 196, 1, 0, 0, 0, 3, 198, 1, 0, 0, 0, 3, 200, 1, 0, 0, 0, 3, 202, 1, 0, 0, 0, 3, 204, 1, 0, 0, 0, 3, 206, 1, 0, 0, 0, 3, 208, 1, 0, 0, 0, 3, 210, 1, 0, 0, 0, 3, 212, 1, 0, 0, 0, 3, 214, 1, 0, 0, 0, 4, 216, 1, 0, 0, 0, 4, 218, 1, 0, 0, 0, 4, 220, 1, 0, 0, 0, 4, 226, 1, 0, 0, 0, 4, 228, 1, 0, 0, 0, 4, 230, 1, 0, 0, 0, 4, 232, 1, 0, 0, 0, 5, 234, 1, 0, 0, 0, 5, 236, 1, 0, 0, 0, 5, 238, 1, 0, 0, 0, 5, 240, 1, 0, 0, 0, 5, 242, 1, 0, 0, 0, 5, 244, 1, 0, 0, 0, 5, 246, 1, 0, 0, 0, 5, 248, 1, 0, 0, 0, 5, 250, 1, 0, 0, 0, 6, 252, 1, 0, 0, 0, 6, 254, 1, 0, 0, 0, 6, 256, 1, 0, 0, 0, 6, 258, 1, 0, 0, 0, 6, 262, 1, 0, 0, 0, 6, 264, 1, 0, 0, 0, 6, 266, 1, 0, 0, 0, 6, 268, 1, 0, 0, 0, 6, 270, 1, 0, 0, 0, 6, 272, 1, 0, 0, 0, 7, 274, 1, 0, 0, 0, 7, 276, 1, 0, 0, 0, 7, 278, 1, 0, 0, 0, 7, 280, 1, 0, 0, 0, 7, 282, 1, 0, 0, 0, 7, 284, 1, 0, 0, 0, 7, 286, 1, 0, 0, 0, 7, 288, 1, 0, 0, 0, 7, 290, 1, 0, 0, 0, 7, 292, 1, 0, 0, 0, 8, 294, 1, 0, 0, 0, 8, 296, 1, 0, 0, 0, 8, 298, 1, 0, 0, 0, 8, 300, 1, 0, 0, 0, 8, 302, 1, 0, 0, 0, 8, 304, 1, 0, 0, 0, 8, 306, 1, 0, 0, 0, 8, 308, 1, 0, 0, 0, 9, 310, 1, 0, 0, 0, 9, 312, 1, 0, 0, 0, 9, 314, 1, 0, 0, 0, 9, 316, 1, 0, 0, 0, 9, 318, 1, 0, 0, 0, 9, 320, 1, 0, 0, 0, 9, 322, 1, 0, 0, 0, 10, 324, 1, 0, 0, 0, 10, 326, 1, 0, 0, 0, 10, 328, 1, 0, 0, 0, 10, 330, 1, 0, 0, 0, 10, 332, 1, 0, 0, 0, 10, 334, 1, 0, 0, 0, 10, 336, 1, 0, 0, 0, 11, 338, 1, 0, 0, 0, 11, 340, 1, 0, 0, 0, 11, 342, 1, 0, 0, 0, 11, 344, 1, 0, 0, 0, 11, 346, 1, 0, 0, 0, 12, 348, 1, 0, 0, 0, 12, 350, 1, 0, 0, 0, 12, 352, 1, 0, 0, 0, 12, 354, 1, 0, 0, 0, 12, 356, 1, 0, 0, 0, 13, 358, 1, 0, 0, 0, 13, 360, 1, 0, 0, 0, 13, 362, 1, 0, 0, 0, 13, 364, 1, 0, 0, 0, 13, 366, 1, 0, 0, 0, 13, 368, 1, 0, 0, 0, 14, 370, 1, 0, 0, 0, 14, 372, 1, 0, 0, 0, 14, 374, 1, 0, 0, 0, 14, 376, 1, 0, 0, 0, 14, 378, 1, 0, 0, 0, 15, 380, 1, 0, 0, 0, 15, 382, 1, 0, 0, 0, 15, 384, 1, 0, 0, 0, 15, 386, 1, 0, 0, 0, 15, 388, 1, 0, 0, 0, 15, 390, 1, 0, 0, 0, 15, 392, 1, 0, 0, 0, 15, 394, 1, 0, 0, 0, 16, 396, 1, 0, 0, 0, 18, 406, 1, 0, 0, 0, 20, 413, 1, 0, 0, 0, 22, 422, 1, 0, 0, 0, 24, 429, 1, 0, 0, 0, 26, 439, 1, 0, 0, 0, 28, 446, 1, 0, 0, 0, 30, 453, 1, 0, 0, 0, 32, 467, 1, 0, 0, 0, 34, 474, 1, 0, 0, 0, 36, 482, 1, 0, 0, 0, 38, 491, 1, 0, 0, 0, 40, 498, 1, 0, 0, 0, 42, 508, 1, 0, 0, 0, 44, 520, 1, 0, 0, 0, 46, 529, 1, 0, 0, 0, 48, 535, 1, 0, 0, 0, 50, 542, 1, 0, 0, 0, 52, 549, 1, 0, 0, 0, 54, 557, 1, 0, 0, 0, 56, 566, 1, 0, 0, 0, 58, 572, 1, 0, 0, 0, 60, 589, 1, 0, 0, 0, 62, 605, 1, 0, 0, 0, 64, 614, 1, 0, 0, 0, 66, 617, 1, 0, 0, 0, 68, 621, 1, 0, 0, 0, 70, 626, 1, 0, 0, 0, 72, 631, 1, 0, 0, 0, 74, 635, 1, 0, 0, 0, 76, 639, 1, 0, 0, 0, 78, 643, 1, 0, 0, 0, 80, 647, 1, 0, 0, 0, 82, 649, 1, 0, 0, 0, 84, 651, 1, 0, 0, 0, 86, 654, 1, 0, 0, 0, 88, 656, 1, 0, 0, 0, 90, 665, 1, 0, 0, 0, 92, 667, 1, 0, 0, 0, 94, 672, 1, 0, 0, 0, 96, 674, 1, 0, 0, 0, 98, 679, 1, 0, 0, 0, 100, 710, 1, 0, 0, 0, 102, 713, 1, 0, 0, 0, 104, 759, 1, 0, 0, 0, 106, 761, 1, 0, 0, 0, 108, 764, 1, 0, 0, 0, 110, 768, 1, 0, 0, 0, 112, 772, 1, 0, 0, 0, 114, 774, 1, 0, 0, 0, 116, 777, 1, 0, 0, 0, 118, 779, 1, 0, 0, 0, 120, 784, 1, 0, 0, 0, 122, 786, 1, 0, 0, 0, 124, 792, 1, 0, 0, 0, 126, 798, 1, 0, 0, 0, 128, 803, 1, 0, 0, 0, 130, 805, 1, 0, 0, 0, 132, 808, 1, 0, 0, 0, 134, 811, 1, 0, 0, 0, 136, 816, 1, 0, 0, 0, 138, 820, 1, 0, 0, 0, 140, 825, 1, 0, 0, 0, 142, 831, 1, 0, 0, 0, 144, 834, 1, 0, 0, 0, 146, 836, 1, 0, 0, 0, 148, 842, 1, 0, 0, 0, 150, 844, 1, 0, 0, 0, 152, 849, 1, 0, 0, 0, 154, 852, 1, 0, 0, 0, 156, 855, 1, 0, 0, 0, 158, 858, 1, 0, 0, 0, 160, 860, 1, 0, 0, 0, 162, 863, 1, 0, 0, 0, 164, 865, 1, 0, 0, 0, 166, 868, 1, 0, 0, 0, 168, 870, 1, 0, 0, 0, 170, 872, 1, 0, 0, 0, 172, 874, 1, 0, 0, 0, 174, 876, 1, 0, 0, 0, 176, 892, 1, 0, 0, 0, 178, 894, 1, 0, 0, 0, 180, 899, 1, 0, 0, 0, 182, 920, 1, 0, 0, 0, 184, 922, 1, 0, 0, 0, 186, 930, 1, 0, 0, 0, 188, 932, 1, 0, 0, 0, 190, 936, 1, 0, 0, 0, 192, 940, 1, 0, 0, 0, 194, 944, 1, 0, 0, 0, 196, 949, 1, 0, 0, 0, 198, 953, 1, 0, 0, 0, 200, 957, 1, 0, 0, 0, 202, 961, 1, 0, 0, 0, 204, 965, 1, 0, 0, 0, 206, 969, 1, 0, 0, 0, 208, 978, 1, 0, 0, 0, 210, 982, 1, 0, 0, 0, 212, 986, 1, 0, 0, 0, 214, 990, 1, 0, 0, 0, 216, 994, 1, 0, 0, 0, 218, 999, 1, 0, 0, 0, 220, 1003, 1, 0, 0, 0, 222, 1011, 1, 0, 0, 0, 224, 1032, 1, 0, 0, 0, 226, 1036, 1, 0, 0, 0, 228, 1040, 1, 0, 0, 0, 230, 1044, 1, 0, 0, 0, 232, 1048, 1, 0, 0, 0, 234, 1052, 1, 0, 0, 0, 236, 1057, 1, 0, 0, 0, 238, 1061, 1, 0, 0, 0, 240, 1065, 1, 0, 0, 0, 242, 1069, 1, 0, 0, 0, 244, 1072, 1, 0, 0, 0, 246, 1076, 1, 0, 0, 0, 248, 1080, 1, 0, 0, 0, 250, 1084, 1, 0, 0, 0, 252, 1088, 1, 0, 0, 0, 254, 1093, 1, 0, 0, 0, 256, 1098, 1, 0, 0, 0, 258, 1103, 1, 0, 0, 0, 260, 1110, 1, 0, 0, 0, 262, 1119, 1, 0, 0, 0, 264, 1126, 1, 0, 0, 0, 266, 1130, 1, 0, 0, 0, 268, 1134, 1, 0, 0, 0, 270, 1138, 1, 0, 0, 0, 272, 1142, 1, 0, 0, 0, 274, 1146, 1, 0, 0, 0, 276, 1152, 1, 0, 0, 0, 278, 1156, 1, 0, 0, 0, 280, 1160, 1, 0, 0, 0, 282, 1164, 1, 0, 0, 0, 284, 1168, 1, 0, 0, 0, 286, 1172, 1, 0, 0, 0, 288, 1176, 1, 0, 0, 0, 290, 1180, 1, 0, 0, 0, 292, 1184, 1, 0, 0, 0, 294, 1188, 1, 0, 0, 0, 296, 1193, 1, 0, 0, 0, 298, 1197, 1, 0, 0, 0, 300, 1201, 1, 0, 0, 0, 302, 1206, 1, 0, 0, 0, 304, 1210, 1, 0, 0, 0, 306, 1214, 1, 0, 0, 0, 308, 1218, 1, 0, 0, 0, 310, 1222, 1, 0, 0, 0, 312, 1228, 1, 0, 0, 0, 314, 1232, 1, 0, 0, 0, 316, 1236, 1, 0, 0, 0, 318, 1240, 1, 0, 0, 0, 320, 1244, 1, 0, 0, 0, 322, 1248, 1, 0, 0, 0, 324, 1252, 1, 0, 0, 0, 326, 1257, 1, 0, 0, 0, 328, 1261, 1, 0, 0, 0, 330, 1265, 1, 0, 0, 0, 332, 1269, 1, 0, 0, 0, 334, 1273, 1, 0, 0, 0, 336, 1277, 1, 0, 0, 0, 338, 1281, 1, 0, 0, 0, 340, 1286, 1, 0, 0, 0, 342, 1291, 1, 0, 0, 0, 344, 1295, 1, 0, 0, 0, 346, 1299, 1, 0, 0, 0, 348, 1303, 1, 0, 0, 0, 350, 1308, 1, 0, 0, 0, 352, 1318, 1, 0, 0, 0, 354, 1322, 1, 0, 0, 0, 356, 1326, 1, 0, 0, 0, 358, 1330, 1, 0, 0, 0, 360, 1335, 1, 0, 0, 0, 362, 1342, 1, 0, 0, 0, 364, 1346, 1, 0, 0, 0, 366, 1350, 1, 0, 0, 0, 368, 1354, 1, 0, 0, 0, 370, 1358, 1, 0, 0, 0, 372, 1363, 1, 0, 0, 0, 374, 1369, 1, 0, 0, 0, 376, 1373, 1, 0, 0, 0, 378, 1377, 1, 0, 0, 0, 380, 1381, 1, 0, 0, 0, 382, 1387, 1, 0, 0, 0, 384, 1391, 1, 0, 0, 0, 386, 1395, 1, 0, 0, 0, 388, 1399, 1, 0, 0, 0, 390, 1405, 1, 0, 0, 0, 392, 1411, 1, 0, 0, 0, 394, 1417, 1, 0, 0, 0, 396, 397, 5, 100, 0, 0, 397, 398, 5, 105, 0, 0, 398, 399, 5, 115, 0, 0, 399, 400, 5, 115, 0, 0, 400, 401, 5, 101, 0, 0, 401, 402, 5, 99, 0, 0, 402, 403, 5, 116, 0, 0, 403, 404, 1, 0, 0, 0, 404, 405, 6, 0, 0, 0, 405, 17, 1, 0, 0, 0, 406, 407, 5, 100, 0, 0, 407, 408, 5, 114, 0, 0, 408, 409, 5, 111, 0, 0, 409, 410, 5, 112, 0, 0, 410, 411, 1, 0, 0, 0, 411, 412, 6, 1, 1, 0, 412, 19, 1, 0, 0, 0, 413, 414, 5, 101, 0, 0, 414, 415, 5, 110, 0, 0, 415, 416, 5, 114, 0, 0, 416, 417, 5, 105, 0, 0, 417, 418, 5, 99, 0, 0, 418, 419, 5, 104, 0, 0, 419, 420, 1, 0, 0, 0, 420, 421, 6, 2, 2, 0, 421, 21, 1, 0, 0, 0, 422, 423, 5, 101, 0, 0, 423, 424, 5, 118, 0, 0, 424, 425, 5, 97, 0, 0, 425, 426, 5, 108, 0, 0, 426, 427, 1, 0, 0, 0, 427, 428, 6, 3, 0, 0, 428, 23, 1, 0, 0, 0, 429, 430, 5, 101, 0, 0, 430, 431, 5, 120, 0, 0, 431, 432, 5, 112, 0, 0, 432, 433, 5, 108, 0, 0, 433, 434, 5, 97, 0, 0, 434, 435, 5, 105, 0, 0, 435, 436, 5, 110, 0, 0, 436, 437, 1, 0, 0, 0, 437, 438, 6, 4, 3, 0, 438, 25, 1, 0, 0, 0, 439, 440, 5, 102, 0, 0, 440, 441, 5, 114, 0, 0, 441, 442, 5, 111, 0, 0, 442, 443, 5, 109, 0, 0, 443, 444, 1, 0, 0, 0, 444, 445, 6, 5, 4, 0, 445, 27, 1, 0, 0, 0, 446, 447, 5, 103, 0, 0, 447, 448, 5, 114, 0, 0, 448, 449, 5, 111, 0, 0, 449, 450, 5, 107, 0, 0, 450, 451, 1, 0, 0, 0, 451, 452, 6, 6, 0, 0, 452, 29, 1, 0, 0, 0, 453, 454, 5, 105, 0, 0, 454, 455, 5, 110, 0, 0, 455, 456, 5, 108, 0, 0, 456, 457, 5, 105, 0, 0, 457, 458, 5, 110, 0, 0, 458, 459, 5, 101, 0, 0, 459, 460, 5, 115, 0, 0, 460, 461, 5, 116, 0, 0, 461, 462, 5, 97, 0, 0, 462, 463, 5, 116, 0, 0, 463, 464, 5, 115, 0, 0, 464, 465, 1, 0, 0, 0, 465, 466, 6, 7, 0, 0, 466, 31, 1, 0, 0, 0, 467, 468, 5, 107, 0, 0, 468, 469, 5, 101, 0, 0, 469, 470, 5, 101, 0, 0, 470, 471, 5, 112, 0, 0, 471, 472, 1, 0, 0, 0, 472, 473, 6, 8, 1, 0, 473, 33, 1, 0, 0, 0, 474, 475, 5, 108, 0, 0, 475, 476, 5, 105, 0, 0, 476, 477, 5, 109, 0, 0, 477, 478, 5, 105, 0, 0, 478, 479, 5, 116, 0, 0, 479, 480, 1, 0, 0, 0, 480, 481, 6, 9, 0, 0, 481, 35, 1, 0, 0, 0, 482, 483, 5, 108, 0, 0, 483, 484, 5, 111, 0, 0, 484, 485, 5, 111, 0, 0, 485, 486, 5, 107, 0, 0, 486, 487, 5, 117, 0, 0, 487, 488, 5, 112, 0, 0, 488, 489, 1, 0, 0, 0, 489, 490, 6, 10, 5, 0, 490, 37, 1, 0, 0, 0, 491, 492, 5, 109, 0, 0, 492, 493, 5, 101, 0, 0, 493, 494, 5, 116, 0, 0, 494, 495, 5, 97, 0, 0, 495, 496, 1, 0, 0, 0, 496, 497, 6, 11, 6, 0, 497, 39, 1, 0, 0, 0, 498, 499, 5, 109, 0, 0, 499, 500, 5, 101, 0, 0, 500, 501, 5, 116, 0, 0, 501, 502, 5, 114, 0, 0, 502, 503, 5, 105, 0, 0, 503, 504, 5, 99, 0, 0, 504, 505, 5, 115, 0, 0, 505, 506, 1, 0, 0, 0, 506, 507, 6, 12, 7, 0, 507, 41, 1, 0, 0, 0, 508, 509, 5, 109, 0, 0, 509, 510, 5, 118, 0, 0, 510, 511, 5, 95, 0, 0, 511, 512, 5, 101, 0, 0, 512, 513, 5, 120, 0, 0, 513, 514, 5, 112, 0, 0, 514, 515, 5, 97, 0, 0, 515, 516, 5, 110, 0, 0, 516, 517, 5, 100, 0, 0, 517, 518, 1, 0, 0, 0, 518, 519, 6, 13, 8, 0, 519, 43, 1, 0, 0, 0, 520, 521, 5, 114, 0, 0, 521, 522, 5, 101, 0, 0, 522, 523, 5, 110, 0, 0, 523, 524, 5, 97, 0, 0, 524, 525, 5, 109, 0, 0, 525, 526, 5, 101, 0, 0, 526, 527, 1, 0, 0, 0, 527, 528, 6, 14, 9, 0, 528, 45, 1, 0, 0, 0, 529, 530, 5, 114, 0, 0, 530, 531, 5, 111, 0, 0, 531, 532, 5, 119, 0, 0, 532, 533, 1, 0, 0, 0, 533, 534, 6, 15, 0, 0, 534, 47, 1, 0, 0, 0, 535, 536, 5, 115, 0, 0, 536, 537, 5, 104, 0, 0, 537, 538, 5, 111, 0, 0, 538, 539, 5, 119, 0, 0, 539, 540, 1, 0, 0, 0, 540, 541, 6, 16, 10, 0, 541, 49, 1, 0, 0, 0, 542, 543, 5, 115, 0, 0, 543, 544, 5, 111, 0, 0, 544, 545, 5, 114, 0, 0, 545, 546, 5, 116, 0, 0, 546, 547, 1, 0, 0, 0, 547, 548, 6, 17, 0, 0, 548, 51, 1, 0, 0, 0, 549, 550, 5, 115, 0, 0, 550, 551, 5, 116, 0, 0, 551, 552, 5, 97, 0, 0, 552, 553, 5, 116, 0, 0, 553, 554, 5, 115, 0, 0, 554, 555, 1, 0, 0, 0, 555, 556, 6, 18, 0, 0, 556, 53, 1, 0, 0, 0, 557, 558, 5, 119, 0, 0, 558, 559, 5, 104, 0, 0, 559, 560, 5, 101, 0, 0, 560, 561, 5, 114, 0, 0, 561, 562, 5, 101, 0, 0, 562, 563, 1, 0, 0, 0, 563, 564, 6, 19, 0, 0, 564, 55, 1, 0, 0, 0, 565, 567, 8, 0, 0, 0, 566, 565, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 566, 1, 0, 0, 0, 568, 569, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 570, 571, 6, 20, 0, 0, 571, 57, 1, 0, 0, 0, 572, 573, 5, 47, 0, 0, 573, 574, 5, 47, 0, 0, 574, 578, 1, 0, 0, 0, 575, 577, 8, 1, 0, 0, 576, 575, 1, 0, 0, 0, 577, 580, 1, 0, 0, 0, 578, 576, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 582, 1, 0, 0, 0, 580, 578, 1, 0, 0, 0, 581, 583, 5, 13, 0, 0, 582, 581, 1, 0, 0, 0, 582, 583, 1, 0, 0, 0, 583, 585, 1, 0, 0, 0, 584, 586, 5, 10, 0, 0, 585, 584, 1, 0, 0, 0, 585, 586, 1, 0, 0, 0, 586, 587, 1, 0, 0, 0, 587, 588, 6, 21, 11, 0, 588, 59, 1, 0, 0, 0, 589, 590, 5, 47, 0, 0, 590, 591, 5, 42, 0, 0, 591, 596, 1, 0, 0, 0, 592, 595, 3, 60, 22, 0, 593, 595, 9, 0, 0, 0, 594, 592, 1, 0, 0, 0, 594, 593, 1, 0, 0, 0, 595, 598, 1, 0, 0, 0, 596, 597, 1, 0, 0, 0, 596, 594, 1, 0, 0, 0, 597, 599, 1, 0, 0, 0, 598, 596, 1, 0, 0, 0, 599, 600, 5, 42, 0, 0, 600, 601, 5, 47, 0, 0, 601, 602, 1, 0, 0, 0, 602, 603, 6, 22, 11, 0, 603, 61, 1, 0, 0, 0, 604, 606, 7, 2, 0, 0, 605, 604, 1, 0, 0, 0, 606, 607, 1, 0, 0, 0, 607, 605, 1, 0, 0, 0, 607, 608, 1, 0, 0, 0, 608, 609, 1, 0, 0, 0, 609, 610, 6, 23, 11, 0, 610, 63, 1, 0, 0, 0, 611, 615, 8, 3, 0, 0, 612, 613, 5, 47, 0, 0, 613, 615, 8, 4, 0, 0, 614, 611, 1, 0, 0, 0, 614, 612, 1, 0, 0, 0, 615, 65, 1, 0, 0, 0, 616, 618, 3, 64, 24, 0, 617, 616, 1, 0, 0, 0, 618, 619, 1, 0, 0, 0, 619, 617, 1, 0, 0, 0, 619, 620, 1, 0, 0, 0, 620, 67, 1, 0, 0, 0, 621, 622, 3, 178, 81, 0, 622, 623, 1, 0, 0, 0, 623, 624, 6, 26, 12, 0, 624, 625, 6, 26, 13, 0, 625, 69, 1, 0, 0, 0, 626, 627, 3, 78, 31, 0, 627, 628, 1, 0, 0, 0, 628, 629, 6, 27, 14, 0, 629, 630, 6, 27, 15, 0, 630, 71, 1, 0, 0, 0, 631, 632, 3, 62, 23, 0, 632, 633, 1, 0, 0, 0, 633, 634, 6, 28, 11, 0, 634, 73, 1, 0, 0, 0, 635, 636, 3, 58, 21, 0, 636, 637, 1, 0, 0, 0, 637, 638, 6, 29, 11, 0, 638, 75, 1, 0, 0, 0, 639, 640, 3, 60, 22, 0, 640, 641, 1, 0, 0, 0, 641, 642, 6, 30, 11, 0, 642, 77, 1, 0, 0, 0, 643, 644, 5, 124, 0, 0, 644, 645, 1, 0, 0, 0, 645, 646, 6, 31, 15, 0, 646, 79, 1, 0, 0, 0, 647, 648, 7, 5, 0, 0, 648, 81, 1, 0, 0, 0, 649, 650, 7, 6, 0, 0, 650, 83, 1, 0, 0, 0, 651, 652, 5, 92, 0, 0, 652, 653, 7, 7, 0, 0, 653, 85, 1, 0, 0, 0, 654, 655, 8, 8, 0, 0, 655, 87, 1, 0, 0, 0, 656, 658, 7, 9, 0, 0, 657, 659, 7, 10, 0, 0, 658, 657, 1, 0, 0, 0, 658, 659, 1, 0, 0, 0, 659, 661, 1, 0, 0, 0, 660, 662, 3, 80, 32, 0, 661, 660, 1, 0, 0, 0, 662, 663, 1, 0, 0, 0, 663, 661, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 89, 1, 0, 0, 0, 665, 666, 5, 64, 0, 0, 666, 91, 1, 0, 0, 0, 667, 668, 5, 96, 0, 0, 668, 93, 1, 0, 0, 0, 669, 673, 8, 11, 0, 0, 670, 671, 5, 96, 0, 0, 671, 673, 5, 96, 0, 0, 672, 669, 1, 0, 0, 0, 672, 670, 1, 0, 0, 0, 673, 95, 1, 0, 0, 0, 674, 675, 5, 95, 0, 0, 675, 97, 1, 0, 0, 0, 676, 680, 3, 82, 33, 0, 677, 680, 3, 80, 32, 0, 678, 680, 3, 96, 40, 0, 679, 676, 1, 0, 0, 0, 679, 677, 1, 0, 0, 0, 679, 678, 1, 0, 0, 0, 680, 99, 1, 0, 0, 0, 681, 686, 5, 34, 0, 0, 682, 685, 3, 84, 34, 0, 683, 685, 3, 86, 35, 0, 684, 682, 1, 0, 0, 0, 684, 683, 1, 0, 0, 0, 685, 688, 1, 0, 0, 0, 686, 684, 1, 0, 0, 0, 686, 687, 1, 0, 0, 0, 687, 689, 1, 0, 0, 0, 688, 686, 1, 0, 0, 0, 689, 711, 5, 34, 0, 0, 690, 691, 5, 34, 0, 0, 691, 692, 5, 34, 0, 0, 692, 693, 5, 34, 0, 0, 693, 697, 1, 0, 0, 0, 694, 696, 8, 1, 0, 0, 695, 694, 1, 0, 0, 0, 696, 699, 1, 0, 0, 0, 697, 698, 1, 0, 0, 0, 697, 695, 1, 0, 0, 0, 698, 700, 1, 0, 0, 0, 699, 697, 1, 0, 0, 0, 700, 701, 5, 34, 0, 0, 701, 702, 5, 34, 0, 0, 702, 703, 5, 34, 0, 0, 703, 705, 1, 0, 0, 0, 704, 706, 5, 34, 0, 0, 705, 704, 1, 0, 0, 0, 705, 706, 1, 0, 0, 0, 706, 708, 1, 0, 0, 0, 707, 709, 5, 34, 0, 0, 708, 707, 1, 0, 0, 0, 708, 709, 1, 0, 0, 0, 709, 711, 1, 0, 0, 0, 710, 681, 1, 0, 0, 0, 710, 690, 1, 0, 0, 0, 711, 101, 1, 0, 0, 0, 712, 714, 3, 80, 32, 0, 713, 712, 1, 0, 0, 0, 714, 715, 1, 0, 0, 0, 715, 713, 1, 0, 0, 0, 715, 716, 1, 0, 0, 0, 716, 103, 1, 0, 0, 0, 717, 719, 3, 80, 32, 0, 718, 717, 1, 0, 0, 0, 719, 720, 1, 0, 0, 0, 720, 718, 1, 0, 0, 0, 720, 721, 1, 0, 0, 0, 721, 722, 1, 0, 0, 0, 722, 726, 3, 120, 52, 0, 723, 725, 3, 80, 32, 0, 724, 723, 1, 0, 0, 0, 725, 728, 1, 0, 0, 0, 726, 724, 1, 0, 0, 0, 726, 727, 1, 0, 0, 0, 727, 760, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 729, 731, 3, 120, 52, 0, 730, 732, 3, 80, 32, 0, 731, 730, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 731, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 760, 1, 0, 0, 0, 735, 737, 3, 80, 32, 0, 736, 735, 1, 0, 0, 0, 737, 738, 1, 0, 0, 0, 738, 736, 1, 0, 0, 0, 738, 739, 1, 0, 0, 0, 739, 747, 1, 0, 0, 0, 740, 744, 3, 120, 52, 0, 741, 743, 3, 80, 32, 0, 742, 741, 1, 0, 0, 0, 743, 746, 1, 0, 0, 0, 744, 742, 1, 0, 0, 0, 744, 745, 1, 0, 0, 0, 745, 748, 1, 0, 0, 0, 746, 744, 1, 0, 0, 0, 747, 740, 1, 0, 0, 0, 747, 748, 1, 0, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 3, 88, 36, 0, 750, 760, 1, 0, 0, 0, 751, 753, 3, 120, 52, 0, 752, 754, 3, 80, 32, 0, 753, 752, 1, 0, 0, 0, 754, 755, 1, 0, 0, 0, 755, 753, 1, 0, 0, 0, 755, 756, 1, 0, 0, 0, 756, 757, 1, 0, 0, 0, 757, 758, 3, 88, 36, 0, 758, 760, 1, 0, 0, 0, 759, 718, 1, 0, 0, 0, 759, 729, 1, 0, 0, 0, 759, 736, 1, 0, 0, 0, 759, 751, 1, 0, 0, 0, 760, 105, 1, 0, 0, 0, 761, 762, 5, 98, 0, 0, 762, 763, 5, 121, 0, 0, 763, 107, 1, 0, 0, 0, 764, 765, 5, 97, 0, 0, 765, 766, 5, 110, 0, 0, 766, 767, 5, 100, 0, 0, 767, 109, 1, 0, 0, 0, 768, 769, 5, 97, 0, 0, 769, 770, 5, 115, 0, 0, 770, 771, 5, 99, 0, 0, 771, 111, 1, 0, 0, 0, 772, 773, 5, 61, 0, 0, 773, 113, 1, 0, 0, 0, 774, 775, 5, 58, 0, 0, 775, 776, 5, 58, 0, 0, 776, 115, 1, 0, 0, 0, 777, 778, 5, 44, 0, 0, 778, 117, 1, 0, 0, 0, 779, 780, 5, 100, 0, 0, 780, 781, 5, 101, 0, 0, 781, 782, 5, 115, 0, 0, 782, 783, 5, 99, 0, 0, 783, 119, 1, 0, 0, 0, 784, 785, 5, 46, 0, 0, 785, 121, 1, 0, 0, 0, 786, 787, 5, 102, 0, 0, 787, 788, 5, 97, 0, 0, 788, 789, 5, 108, 0, 0, 789, 790, 5, 115, 0, 0, 790, 791, 5, 101, 0, 0, 791, 123, 1, 0, 0, 0, 792, 793, 5, 102, 0, 0, 793, 794, 5, 105, 0, 0, 794, 795, 5, 114, 0, 0, 795, 796, 5, 115, 0, 0, 796, 797, 5, 116, 0, 0, 797, 125, 1, 0, 0, 0, 798, 799, 5, 108, 0, 0, 799, 800, 5, 97, 0, 0, 800, 801, 5, 115, 0, 0, 801, 802, 5, 116, 0, 0, 802, 127, 1, 0, 0, 0, 803, 804, 5, 40, 0, 0, 804, 129, 1, 0, 0, 0, 805, 806, 5, 105, 0, 0, 806, 807, 5, 110, 0, 0, 807, 131, 1, 0, 0, 0, 808, 809, 5, 105, 0, 0, 809, 810, 5, 115, 0, 0, 810, 133, 1, 0, 0, 0, 811, 812, 5, 108, 0, 0, 812, 813, 5, 105, 0, 0, 813, 814, 5, 107, 0, 0, 814, 815, 5, 101, 0, 0, 815, 135, 1, 0, 0, 0, 816, 817, 5, 110, 0, 0, 817, 818, 5, 111, 0, 0, 818, 819, 5, 116, 0, 0, 819, 137, 1, 0, 0, 0, 820, 821, 5, 110, 0, 0, 821, 822, 5, 117, 0, 0, 822, 823, 5, 108, 0, 0, 823, 824, 5, 108, 0, 0, 824, 139, 1, 0, 0, 0, 825, 826, 5, 110, 0, 0, 826, 827, 5, 117, 0, 0, 827, 828, 5, 108, 0, 0, 828, 829, 5, 108, 0, 0, 829, 830, 5, 115, 0, 0, 830, 141, 1, 0, 0, 0, 831, 832, 5, 111, 0, 0, 832, 833, 5, 114, 0, 0, 833, 143, 1, 0, 0, 0, 834, 835, 5, 63, 0, 0, 835, 145, 1, 0, 0, 0, 836, 837, 5, 114, 0, 0, 837, 838, 5, 108, 0, 0, 838, 839, 5, 105, 0, 0, 839, 840, 5, 107, 0, 0, 840, 841, 5, 101, 0, 0, 841, 147, 1, 0, 0, 0, 842, 843, 5, 41, 0, 0, 843, 149, 1, 0, 0, 0, 844, 845, 5, 116, 0, 0, 845, 846, 5, 114, 0, 0, 846, 847, 5, 117, 0, 0, 847, 848, 5, 101, 0, 0, 848, 151, 1, 0, 0, 0, 849, 850, 5, 61, 0, 0, 850, 851, 5, 61, 0, 0, 851, 153, 1, 0, 0, 0, 852, 853, 5, 61, 0, 0, 853, 854, 5, 126, 0, 0, 854, 155, 1, 0, 0, 0, 855, 856, 5, 33, 0, 0, 856, 857, 5, 61, 0, 0, 857, 157, 1, 0, 0, 0, 858, 859, 5, 60, 0, 0, 859, 159, 1, 0, 0, 0, 860, 861, 5, 60, 0, 0, 861, 862, 5, 61, 0, 0, 862, 161, 1, 0, 0, 0, 863, 864, 5, 62, 0, 0, 864, 163, 1, 0, 0, 0, 865, 866, 5, 62, 0, 0, 866, 867, 5, 61, 0, 0, 867, 165, 1, 0, 0, 0, 868, 869, 5, 43, 0, 0, 869, 167, 1, 0, 0, 0, 870, 871, 5, 45, 0, 0, 871, 169, 1, 0, 0, 0, 872, 873, 5, 42, 0, 0, 873, 171, 1, 0, 0, 0, 874, 875, 5, 47, 0, 0, 875, 173, 1, 0, 0, 0, 876, 877, 5, 37, 0, 0, 877, 175, 1, 0, 0, 0, 878, 879, 3, 144, 64, 0, 879, 883, 3, 82, 33, 0, 880, 882, 3, 98, 41, 0, 881, 880, 1, 0, 0, 0, 882, 885, 1, 0, 0, 0, 883, 881, 1, 0, 0, 0, 883, 884, 1, 0, 0, 0, 884, 893, 1, 0, 0, 0, 885, 883, 1, 0, 0, 0, 886, 888, 3, 144, 64, 0, 887, 889, 3, 80, 32, 0, 888, 887, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 888, 1, 0, 0, 0, 890, 891, 1, 0, 0, 0, 891, 893, 1, 0, 0, 0, 892, 878, 1, 0, 0, 0, 892, 886, 1, 0, 0, 0, 893, 177, 1, 0, 0, 0, 894, 895, 5, 91, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 6, 81, 0, 0, 897, 898, 6, 81, 0, 0, 898, 179, 1, 0, 0, 0, 899, 900, 5, 93, 0, 0, 900, 901, 1, 0, 0, 0, 901, 902, 6, 82, 15, 0, 902, 903, 6, 82, 15, 0, 903, 181, 1, 0, 0, 0, 904, 908, 3, 82, 33, 0, 905, 907, 3, 98, 41, 0, 906, 905, 1, 0, 0, 0, 907, 910, 1, 0, 0, 0, 908, 906, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 921, 1, 0, 0, 0, 910, 908, 1, 0, 0, 0, 911, 914, 3, 96, 40, 0, 912, 914, 3, 90, 37, 0, 913, 911, 1, 0, 0, 0, 913, 912, 1, 0, 0, 0, 914, 916, 1, 0, 0, 0, 915, 917, 3, 98, 41, 0, 916, 915, 1, 0, 0, 0, 917, 918, 1, 0, 0, 0, 918, 916, 1, 0, 0, 0, 918, 919, 1, 0, 0, 0, 919, 921, 1, 0, 0, 0, 920, 904, 1, 0, 0, 0, 920, 913, 1, 0, 0, 0, 921, 183, 1, 0, 0, 0, 922, 924, 3, 92, 38, 0, 923, 925, 3, 94, 39, 0, 924, 923, 1, 0, 0, 0, 925, 926, 1, 0, 0, 0, 926, 924, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 1, 0, 0, 0, 928, 929, 3, 92, 38, 0, 929, 185, 1, 0, 0, 0, 930, 931, 3, 184, 84, 0, 931, 187, 1, 0, 0, 0, 932, 933, 3, 58, 21, 0, 933, 934, 1, 0, 0, 0, 934, 935, 6, 86, 11, 0, 935, 189, 1, 0, 0, 0, 936, 937, 3, 60, 22, 0, 937, 938, 1, 0, 0, 0, 938, 939, 6, 87, 11, 0, 939, 191, 1, 0, 0, 0, 940, 941, 3, 62, 23, 0, 941, 942, 1, 0, 0, 0, 942, 943, 6, 88, 11, 0, 943, 193, 1, 0, 0, 0, 944, 945, 3, 78, 31, 0, 945, 946, 1, 0, 0, 0, 946, 947, 6, 89, 14, 0, 947, 948, 6, 89, 15, 0, 948, 195, 1, 0, 0, 0, 949, 950, 3, 178, 81, 0, 950, 951, 1, 0, 0, 0, 951, 952, 6, 90, 12, 0, 952, 197, 1, 0, 0, 0, 953, 954, 3, 180, 82, 0, 954, 955, 1, 0, 0, 0, 955, 956, 6, 91, 16, 0, 956, 199, 1, 0, 0, 0, 957, 958, 3, 116, 50, 0, 958, 959, 1, 0, 0, 0, 959, 960, 6, 92, 17, 0, 960, 201, 1, 0, 0, 0, 961, 962, 3, 112, 48, 0, 962, 963, 1, 0, 0, 0, 963, 964, 6, 93, 18, 0, 964, 203, 1, 0, 0, 0, 965, 966, 3, 100, 42, 0, 966, 967, 1, 0, 0, 0, 967, 968, 6, 94, 19, 0, 968, 205, 1, 0, 0, 0, 969, 970, 5, 109, 0, 0, 970, 971, 5, 101, 0, 0, 971, 972, 5, 116, 0, 0, 972, 973, 5, 97, 0, 0, 973, 974, 5, 100, 0, 0, 974, 975, 5, 97, 0, 0, 975, 976, 5, 116, 0, 0, 976, 977, 5, 97, 0, 0, 977, 207, 1, 0, 0, 0, 978, 979, 3, 66, 25, 0, 979, 980, 1, 0, 0, 0, 980, 981, 6, 96, 20, 0, 981, 209, 1, 0, 0, 0, 982, 983, 3, 58, 21, 0, 983, 984, 1, 0, 0, 0, 984, 985, 6, 97, 11, 0, 985, 211, 1, 0, 0, 0, 986, 987, 3, 60, 22, 0, 987, 988, 1, 0, 0, 0, 988, 989, 6, 98, 11, 0, 989, 213, 1, 0, 0, 0, 990, 991, 3, 62, 23, 0, 991, 992, 1, 0, 0, 0, 992, 993, 6, 99, 11, 0, 993, 215, 1, 0, 0, 0, 994, 995, 3, 78, 31, 0, 995, 996, 1, 0, 0, 0, 996, 997, 6, 100, 14, 0, 997, 998, 6, 100, 15, 0, 998, 217, 1, 0, 0, 0, 999, 1000, 3, 120, 52, 0, 1000, 1001, 1, 0, 0, 0, 1001, 1002, 6, 101, 21, 0, 1002, 219, 1, 0, 0, 0, 1003, 1004, 3, 116, 50, 0, 1004, 1005, 1, 0, 0, 0, 1005, 1006, 6, 102, 17, 0, 1006, 221, 1, 0, 0, 0, 1007, 1012, 3, 82, 33, 0, 1008, 1012, 3, 80, 32, 0, 1009, 1012, 3, 96, 40, 0, 1010, 1012, 3, 170, 77, 0, 1011, 1007, 1, 0, 0, 0, 1011, 1008, 1, 0, 0, 0, 1011, 1009, 1, 0, 0, 0, 1011, 1010, 1, 0, 0, 0, 1012, 223, 1, 0, 0, 0, 1013, 1016, 3, 82, 33, 0, 1014, 1016, 3, 170, 77, 0, 1015, 1013, 1, 0, 0, 0, 1015, 1014, 1, 0, 0, 0, 1016, 1020, 1, 0, 0, 0, 1017, 1019, 3, 222, 103, 0, 1018, 1017, 1, 0, 0, 0, 1019, 1022, 1, 0, 0, 0, 1020, 1018, 1, 0, 0, 0, 1020, 1021, 1, 0, 0, 0, 1021, 1033, 1, 0, 0, 0, 1022, 1020, 1, 0, 0, 0, 1023, 1026, 3, 96, 40, 0, 1024, 1026, 3, 90, 37, 0, 1025, 1023, 1, 0, 0, 0, 1025, 1024, 1, 0, 0, 0, 1026, 1028, 1, 0, 0, 0, 1027, 1029, 3, 222, 103, 0, 1028, 1027, 1, 0, 0, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1028, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1033, 1, 0, 0, 0, 1032, 1015, 1, 0, 0, 0, 1032, 1025, 1, 0, 0, 0, 1033, 225, 1, 0, 0, 0, 1034, 1037, 3, 224, 104, 0, 1035, 1037, 3, 184, 84, 0, 1036, 1034, 1, 0, 0, 0, 1036, 1035, 1, 0, 0, 0, 1037, 1038, 1, 0, 0, 0, 1038, 1036, 1, 0, 0, 0, 1038, 1039, 1, 0, 0, 0, 1039, 227, 1, 0, 0, 0, 1040, 1041, 3, 58, 21, 0, 1041, 1042, 1, 0, 0, 0, 1042, 1043, 6, 106, 11, 0, 1043, 229, 1, 0, 0, 0, 1044, 1045, 3, 60, 22, 0, 1045, 1046, 1, 0, 0, 0, 1046, 1047, 6, 107, 11, 0, 1047, 231, 1, 0, 0, 0, 1048, 1049, 3, 62, 23, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1051, 6, 108, 11, 0, 1051, 233, 1, 0, 0, 0, 1052, 1053, 3, 78, 31, 0, 1053, 1054, 1, 0, 0, 0, 1054, 1055, 6, 109, 14, 0, 1055, 1056, 6, 109, 15, 0, 1056, 235, 1, 0, 0, 0, 1057, 1058, 3, 112, 48, 0, 1058, 1059, 1, 0, 0, 0, 1059, 1060, 6, 110, 18, 0, 1060, 237, 1, 0, 0, 0, 1061, 1062, 3, 116, 50, 0, 1062, 1063, 1, 0, 0, 0, 1063, 1064, 6, 111, 17, 0, 1064, 239, 1, 0, 0, 0, 1065, 1066, 3, 120, 52, 0, 1066, 1067, 1, 0, 0, 0, 1067, 1068, 6, 112, 21, 0, 1068, 241, 1, 0, 0, 0, 1069, 1070, 5, 97, 0, 0, 1070, 1071, 5, 115, 0, 0, 1071, 243, 1, 0, 0, 0, 1072, 1073, 3, 226, 105, 0, 1073, 1074, 1, 0, 0, 0, 1074, 1075, 6, 114, 22, 0, 1075, 245, 1, 0, 0, 0, 1076, 1077, 3, 58, 21, 0, 1077, 1078, 1, 0, 0, 0, 1078, 1079, 6, 115, 11, 0, 1079, 247, 1, 0, 0, 0, 1080, 1081, 3, 60, 22, 0, 1081, 1082, 1, 0, 0, 0, 1082, 1083, 6, 116, 11, 0, 1083, 249, 1, 0, 0, 0, 1084, 1085, 3, 62, 23, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 6, 117, 11, 0, 1087, 251, 1, 0, 0, 0, 1088, 1089, 3, 78, 31, 0, 1089, 1090, 1, 0, 0, 0, 1090, 1091, 6, 118, 14, 0, 1091, 1092, 6, 118, 15, 0, 1092, 253, 1, 0, 0, 0, 1093, 1094, 3, 178, 81, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1096, 6, 119, 12, 0, 1096, 1097, 6, 119, 23, 0, 1097, 255, 1, 0, 0, 0, 1098, 1099, 5, 111, 0, 0, 1099, 1100, 5, 110, 0, 0, 1100, 1101, 1, 0, 0, 0, 1101, 1102, 6, 120, 24, 0, 1102, 257, 1, 0, 0, 0, 1103, 1104, 5, 119, 0, 0, 1104, 1105, 5, 105, 0, 0, 1105, 1106, 5, 116, 0, 0, 1106, 1107, 5, 104, 0, 0, 1107, 1108, 1, 0, 0, 0, 1108, 1109, 6, 121, 24, 0, 1109, 259, 1, 0, 0, 0, 1110, 1111, 8, 12, 0, 0, 1111, 261, 1, 0, 0, 0, 1112, 1114, 3, 260, 122, 0, 1113, 1112, 1, 0, 0, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1113, 1, 0, 0, 0, 1115, 1116, 1, 0, 0, 0, 1116, 1117, 1, 0, 0, 0, 1117, 1118, 3, 360, 172, 0, 1118, 1120, 1, 0, 0, 0, 1119, 1113, 1, 0, 0, 0, 1119, 1120, 1, 0, 0, 0, 1120, 1122, 1, 0, 0, 0, 1121, 1123, 3, 260, 122, 0, 1122, 1121, 1, 0, 0, 0, 1123, 1124, 1, 0, 0, 0, 1124, 1122, 1, 0, 0, 0, 1124, 1125, 1, 0, 0, 0, 1125, 263, 1, 0, 0, 0, 1126, 1127, 3, 186, 85, 0, 1127, 1128, 1, 0, 0, 0, 1128, 1129, 6, 124, 25, 0, 1129, 265, 1, 0, 0, 0, 1130, 1131, 3, 262, 123, 0, 1131, 1132, 1, 0, 0, 0, 1132, 1133, 6, 125, 26, 0, 1133, 267, 1, 0, 0, 0, 1134, 1135, 3, 58, 21, 0, 1135, 1136, 1, 0, 0, 0, 1136, 1137, 6, 126, 11, 0, 1137, 269, 1, 0, 0, 0, 1138, 1139, 3, 60, 22, 0, 1139, 1140, 1, 0, 0, 0, 1140, 1141, 6, 127, 11, 0, 1141, 271, 1, 0, 0, 0, 1142, 1143, 3, 62, 23, 0, 1143, 1144, 1, 0, 0, 0, 1144, 1145, 6, 128, 11, 0, 1145, 273, 1, 0, 0, 0, 1146, 1147, 3, 78, 31, 0, 1147, 1148, 1, 0, 0, 0, 1148, 1149, 6, 129, 14, 0, 1149, 1150, 6, 129, 15, 0, 1150, 1151, 6, 129, 15, 0, 1151, 275, 1, 0, 0, 0, 1152, 1153, 3, 112, 48, 0, 1153, 1154, 1, 0, 0, 0, 1154, 1155, 6, 130, 18, 0, 1155, 277, 1, 0, 0, 0, 1156, 1157, 3, 116, 50, 0, 1157, 1158, 1, 0, 0, 0, 1158, 1159, 6, 131, 17, 0, 1159, 279, 1, 0, 0, 0, 1160, 1161, 3, 120, 52, 0, 1161, 1162, 1, 0, 0, 0, 1162, 1163, 6, 132, 21, 0, 1163, 281, 1, 0, 0, 0, 1164, 1165, 3, 258, 121, 0, 1165, 1166, 1, 0, 0, 0, 1166, 1167, 6, 133, 27, 0, 1167, 283, 1, 0, 0, 0, 1168, 1169, 3, 226, 105, 0, 1169, 1170, 1, 0, 0, 0, 1170, 1171, 6, 134, 22, 0, 1171, 285, 1, 0, 0, 0, 1172, 1173, 3, 186, 85, 0, 1173, 1174, 1, 0, 0, 0, 1174, 1175, 6, 135, 25, 0, 1175, 287, 1, 0, 0, 0, 1176, 1177, 3, 58, 21, 0, 1177, 1178, 1, 0, 0, 0, 1178, 1179, 6, 136, 11, 0, 1179, 289, 1, 0, 0, 0, 1180, 1181, 3, 60, 22, 0, 1181, 1182, 1, 0, 0, 0, 1182, 1183, 6, 137, 11, 0, 1183, 291, 1, 0, 0, 0, 1184, 1185, 3, 62, 23, 0, 1185, 1186, 1, 0, 0, 0, 1186, 1187, 6, 138, 11, 0, 1187, 293, 1, 0, 0, 0, 1188, 1189, 3, 78, 31, 0, 1189, 1190, 1, 0, 0, 0, 1190, 1191, 6, 139, 14, 0, 1191, 1192, 6, 139, 15, 0, 1192, 295, 1, 0, 0, 0, 1193, 1194, 3, 116, 50, 0, 1194, 1195, 1, 0, 0, 0, 1195, 1196, 6, 140, 17, 0, 1196, 297, 1, 0, 0, 0, 1197, 1198, 3, 120, 52, 0, 1198, 1199, 1, 0, 0, 0, 1199, 1200, 6, 141, 21, 0, 1200, 299, 1, 0, 0, 0, 1201, 1202, 3, 256, 120, 0, 1202, 1203, 1, 0, 0, 0, 1203, 1204, 6, 142, 28, 0, 1204, 1205, 6, 142, 29, 0, 1205, 301, 1, 0, 0, 0, 1206, 1207, 3, 66, 25, 0, 1207, 1208, 1, 0, 0, 0, 1208, 1209, 6, 143, 20, 0, 1209, 303, 1, 0, 0, 0, 1210, 1211, 3, 58, 21, 0, 1211, 1212, 1, 0, 0, 0, 1212, 1213, 6, 144, 11, 0, 1213, 305, 1, 0, 0, 0, 1214, 1215, 3, 60, 22, 0, 1215, 1216, 1, 0, 0, 0, 1216, 1217, 6, 145, 11, 0, 1217, 307, 1, 0, 0, 0, 1218, 1219, 3, 62, 23, 0, 1219, 1220, 1, 0, 0, 0, 1220, 1221, 6, 146, 11, 0, 1221, 309, 1, 0, 0, 0, 1222, 1223, 3, 78, 31, 0, 1223, 1224, 1, 0, 0, 0, 1224, 1225, 6, 147, 14, 0, 1225, 1226, 6, 147, 15, 0, 1226, 1227, 6, 147, 15, 0, 1227, 311, 1, 0, 0, 0, 1228, 1229, 3, 116, 50, 0, 1229, 1230, 1, 0, 0, 0, 1230, 1231, 6, 148, 17, 0, 1231, 313, 1, 0, 0, 0, 1232, 1233, 3, 120, 52, 0, 1233, 1234, 1, 0, 0, 0, 1234, 1235, 6, 149, 21, 0, 1235, 315, 1, 0, 0, 0, 1236, 1237, 3, 226, 105, 0, 1237, 1238, 1, 0, 0, 0, 1238, 1239, 6, 150, 22, 0, 1239, 317, 1, 0, 0, 0, 1240, 1241, 3, 58, 21, 0, 1241, 1242, 1, 0, 0, 0, 1242, 1243, 6, 151, 11, 0, 1243, 319, 1, 0, 0, 0, 1244, 1245, 3, 60, 22, 0, 1245, 1246, 1, 0, 0, 0, 1246, 1247, 6, 152, 11, 0, 1247, 321, 1, 0, 0, 0, 1248, 1249, 3, 62, 23, 0, 1249, 1250, 1, 0, 0, 0, 1250, 1251, 6, 153, 11, 0, 1251, 323, 1, 0, 0, 0, 1252, 1253, 3, 78, 31, 0, 1253, 1254, 1, 0, 0, 0, 1254, 1255, 6, 154, 14, 0, 1255, 1256, 6, 154, 15, 0, 1256, 325, 1, 0, 0, 0, 1257, 1258, 3, 120, 52, 0, 1258, 1259, 1, 0, 0, 0, 1259, 1260, 6, 155, 21, 0, 1260, 327, 1, 0, 0, 0, 1261, 1262, 3, 186, 85, 0, 1262, 1263, 1, 0, 0, 0, 1263, 1264, 6, 156, 25, 0, 1264, 329, 1, 0, 0, 0, 1265, 1266, 3, 182, 83, 0, 1266, 1267, 1, 0, 0, 0, 1267, 1268, 6, 157, 30, 0, 1268, 331, 1, 0, 0, 0, 1269, 1270, 3, 58, 21, 0, 1270, 1271, 1, 0, 0, 0, 1271, 1272, 6, 158, 11, 0, 1272, 333, 1, 0, 0, 0, 1273, 1274, 3, 60, 22, 0, 1274, 1275, 1, 0, 0, 0, 1275, 1276, 6, 159, 11, 0, 1276, 335, 1, 0, 0, 0, 1277, 1278, 3, 62, 23, 0, 1278, 1279, 1, 0, 0, 0, 1279, 1280, 6, 160, 11, 0, 1280, 337, 1, 0, 0, 0, 1281, 1282, 3, 78, 31, 0, 1282, 1283, 1, 0, 0, 0, 1283, 1284, 6, 161, 14, 0, 1284, 1285, 6, 161, 15, 0, 1285, 339, 1, 0, 0, 0, 1286, 1287, 5, 105, 0, 0, 1287, 1288, 5, 110, 0, 0, 1288, 1289, 5, 102, 0, 0, 1289, 1290, 5, 111, 0, 0, 1290, 341, 1, 0, 0, 0, 1291, 1292, 3, 58, 21, 0, 1292, 1293, 1, 0, 0, 0, 1293, 1294, 6, 163, 11, 0, 1294, 343, 1, 0, 0, 0, 1295, 1296, 3, 60, 22, 0, 1296, 1297, 1, 0, 0, 0, 1297, 1298, 6, 164, 11, 0, 1298, 345, 1, 0, 0, 0, 1299, 1300, 3, 62, 23, 0, 1300, 1301, 1, 0, 0, 0, 1301, 1302, 6, 165, 11, 0, 1302, 347, 1, 0, 0, 0, 1303, 1304, 3, 78, 31, 0, 1304, 1305, 1, 0, 0, 0, 1305, 1306, 6, 166, 14, 0, 1306, 1307, 6, 166, 15, 0, 1307, 349, 1, 0, 0, 0, 1308, 1309, 5, 102, 0, 0, 1309, 1310, 5, 117, 0, 0, 1310, 1311, 5, 110, 0, 0, 1311, 1312, 5, 99, 0, 0, 1312, 1313, 5, 116, 0, 0, 1313, 1314, 5, 105, 0, 0, 1314, 1315, 5, 111, 0, 0, 1315, 1316, 5, 110, 0, 0, 1316, 1317, 5, 115, 0, 0, 1317, 351, 1, 0, 0, 0, 1318, 1319, 3, 58, 21, 0, 1319, 1320, 1, 0, 0, 0, 1320, 1321, 6, 168, 11, 0, 1321, 353, 1, 0, 0, 0, 1322, 1323, 3, 60, 22, 0, 1323, 1324, 1, 0, 0, 0, 1324, 1325, 6, 169, 11, 0, 1325, 355, 1, 0, 0, 0, 1326, 1327, 3, 62, 23, 0, 1327, 1328, 1, 0, 0, 0, 1328, 1329, 6, 170, 11, 0, 1329, 357, 1, 0, 0, 0, 1330, 1331, 3, 180, 82, 0, 1331, 1332, 1, 0, 0, 0, 1332, 1333, 6, 171, 16, 0, 1333, 1334, 6, 171, 15, 0, 1334, 359, 1, 0, 0, 0, 1335, 1336, 5, 58, 0, 0, 1336, 361, 1, 0, 0, 0, 1337, 1343, 3, 90, 37, 0, 1338, 1343, 3, 80, 32, 0, 1339, 1343, 3, 120, 52, 0, 1340, 1343, 3, 82, 33, 0, 1341, 1343, 3, 96, 40, 0, 1342, 1337, 1, 0, 0, 0, 1342, 1338, 1, 0, 0, 0, 1342, 1339, 1, 0, 0, 0, 1342, 1340, 1, 0, 0, 0, 1342, 1341, 1, 0, 0, 0, 1343, 1344, 1, 0, 0, 0, 1344, 1342, 1, 0, 0, 0, 1344, 1345, 1, 0, 0, 0, 1345, 363, 1, 0, 0, 0, 1346, 1347, 3, 58, 21, 0, 1347, 1348, 1, 0, 0, 0, 1348, 1349, 6, 174, 11, 0, 1349, 365, 1, 0, 0, 0, 1350, 1351, 3, 60, 22, 0, 1351, 1352, 1, 0, 0, 0, 1352, 1353, 6, 175, 11, 0, 1353, 367, 1, 0, 0, 0, 1354, 1355, 3, 62, 23, 0, 1355, 1356, 1, 0, 0, 0, 1356, 1357, 6, 176, 11, 0, 1357, 369, 1, 0, 0, 0, 1358, 1359, 3, 78, 31, 0, 1359, 1360, 1, 0, 0, 0, 1360, 1361, 6, 177, 14, 0, 1361, 1362, 6, 177, 15, 0, 1362, 371, 1, 0, 0, 0, 1363, 1364, 3, 66, 25, 0, 1364, 1365, 1, 0, 0, 0, 1365, 1366, 6, 178, 20, 0, 1366, 1367, 6, 178, 15, 0, 1367, 1368, 6, 178, 31, 0, 1368, 373, 1, 0, 0, 0, 1369, 1370, 3, 58, 21, 0, 1370, 1371, 1, 0, 0, 0, 1371, 1372, 6, 179, 11, 0, 1372, 375, 1, 0, 0, 0, 1373, 1374, 3, 60, 22, 0, 1374, 1375, 1, 0, 0, 0, 1375, 1376, 6, 180, 11, 0, 1376, 377, 1, 0, 0, 0, 1377, 1378, 3, 62, 23, 0, 1378, 1379, 1, 0, 0, 0, 1379, 1380, 6, 181, 11, 0, 1380, 379, 1, 0, 0, 0, 1381, 1382, 3, 116, 50, 0, 1382, 1383, 1, 0, 0, 0, 1383, 1384, 6, 182, 17, 0, 1384, 1385, 6, 182, 15, 0, 1385, 1386, 6, 182, 7, 0, 1386, 381, 1, 0, 0, 0, 1387, 1388, 3, 58, 21, 0, 1388, 1389, 1, 0, 0, 0, 1389, 1390, 6, 183, 11, 0, 1390, 383, 1, 0, 0, 0, 1391, 1392, 3, 60, 22, 0, 1392, 1393, 1, 0, 0, 0, 1393, 1394, 6, 184, 11, 0, 1394, 385, 1, 0, 0, 0, 1395, 1396, 3, 62, 23, 0, 1396, 1397, 1, 0, 0, 0, 1397, 1398, 6, 185, 11, 0, 1398, 387, 1, 0, 0, 0, 1399, 1400, 3, 186, 85, 0, 1400, 1401, 1, 0, 0, 0, 1401, 1402, 6, 186, 15, 0, 1402, 1403, 6, 186, 0, 0, 1403, 1404, 6, 186, 25, 0, 1404, 389, 1, 0, 0, 0, 1405, 1406, 3, 182, 83, 0, 1406, 1407, 1, 0, 0, 0, 1407, 1408, 6, 187, 15, 0, 1408, 1409, 6, 187, 0, 0, 1409, 1410, 6, 187, 30, 0, 1410, 391, 1, 0, 0, 0, 1411, 1412, 3, 106, 45, 0, 1412, 1413, 1, 0, 0, 0, 1413, 1414, 6, 188, 15, 0, 1414, 1415, 6, 188, 0, 0, 1415, 1416, 6, 188, 32, 0, 1416, 393, 1, 0, 0, 0, 1417, 1418, 3, 78, 31, 0, 1418, 1419, 1, 0, 0, 0, 1419, 1420, 6, 189, 14, 0, 1420, 1421, 6, 189, 15, 0, 1421, 395, 1, 0, 0, 0, 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 568, 578, 582, 585, 594, 596, 607, 614, 619, 658, 663, 672, 679, 684, 686, 697, 705, 708, 710, 715, 720, 726, 733, 738, 744, 747, 755, 759, 883, 890, 892, 908, 913, 918, 920, 926, 1011, 1015, 1020, 1025, 1030, 1032, 1036, 1038, 1115, 1119, 1124, 1342, 1344, 33, 5, 2, 0, 5, 4, 0, 5, 6, 0, 5, 1, 0, 5, 3, 0, 5, 8, 0, 5, 12, 0, 5, 14, 0, 5, 10, 0, 5, 5, 0, 5, 11, 0, 0, 1, 0, 7, 69, 0, 5, 0, 0, 7, 29, 0, 4, 0, 0, 7, 70, 0, 7, 38, 0, 7, 36, 0, 7, 30, 0, 7, 25, 0, 7, 40, 0, 7, 80, 0, 5, 13, 0, 5, 7, 0, 7, 72, 0, 7, 90, 0, 7, 89, 0, 7, 88, 0, 5, 9, 0, 7, 71, 0, 5, 15, 0, 7, 33, 0] \ No newline at end of file diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java index f9ca7ff95c84..1511be73d40e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java @@ -26,22 +26,23 @@ public class EsqlBaseLexer extends Lexer { CAST_OP=37, COMMA=38, DESC=39, DOT=40, FALSE=41, FIRST=42, LAST=43, LP=44, IN=45, IS=46, LIKE=47, NOT=48, NULL=49, NULLS=50, OR=51, PARAM=52, RLIKE=53, RP=54, TRUE=55, EQ=56, CIEQ=57, NEQ=58, LT=59, LTE=60, GT=61, GTE=62, - PLUS=63, MINUS=64, ASTERISK=65, SLASH=66, PERCENT=67, OPENING_BRACKET=68, - CLOSING_BRACKET=69, UNQUOTED_IDENTIFIER=70, QUOTED_IDENTIFIER=71, EXPR_LINE_COMMENT=72, - EXPR_MULTILINE_COMMENT=73, EXPR_WS=74, METADATA=75, FROM_LINE_COMMENT=76, - FROM_MULTILINE_COMMENT=77, FROM_WS=78, ID_PATTERN=79, PROJECT_LINE_COMMENT=80, - PROJECT_MULTILINE_COMMENT=81, PROJECT_WS=82, AS=83, RENAME_LINE_COMMENT=84, - RENAME_MULTILINE_COMMENT=85, RENAME_WS=86, ON=87, WITH=88, ENRICH_POLICY_NAME=89, - ENRICH_LINE_COMMENT=90, ENRICH_MULTILINE_COMMENT=91, ENRICH_WS=92, ENRICH_FIELD_LINE_COMMENT=93, - ENRICH_FIELD_MULTILINE_COMMENT=94, ENRICH_FIELD_WS=95, LOOKUP_LINE_COMMENT=96, - LOOKUP_MULTILINE_COMMENT=97, LOOKUP_WS=98, LOOKUP_FIELD_LINE_COMMENT=99, - LOOKUP_FIELD_MULTILINE_COMMENT=100, LOOKUP_FIELD_WS=101, MVEXPAND_LINE_COMMENT=102, - MVEXPAND_MULTILINE_COMMENT=103, MVEXPAND_WS=104, INFO=105, SHOW_LINE_COMMENT=106, - SHOW_MULTILINE_COMMENT=107, SHOW_WS=108, FUNCTIONS=109, META_LINE_COMMENT=110, - META_MULTILINE_COMMENT=111, META_WS=112, COLON=113, SETTING=114, SETTING_LINE_COMMENT=115, - SETTTING_MULTILINE_COMMENT=116, SETTING_WS=117, METRICS_LINE_COMMENT=118, - METRICS_MULTILINE_COMMENT=119, METRICS_WS=120, CLOSING_METRICS_LINE_COMMENT=121, - CLOSING_METRICS_MULTILINE_COMMENT=122, CLOSING_METRICS_WS=123; + PLUS=63, MINUS=64, ASTERISK=65, SLASH=66, PERCENT=67, NAMED_OR_POSITIONAL_PARAM=68, + OPENING_BRACKET=69, CLOSING_BRACKET=70, UNQUOTED_IDENTIFIER=71, QUOTED_IDENTIFIER=72, + EXPR_LINE_COMMENT=73, EXPR_MULTILINE_COMMENT=74, EXPR_WS=75, METADATA=76, + FROM_LINE_COMMENT=77, FROM_MULTILINE_COMMENT=78, FROM_WS=79, ID_PATTERN=80, + PROJECT_LINE_COMMENT=81, PROJECT_MULTILINE_COMMENT=82, PROJECT_WS=83, + AS=84, RENAME_LINE_COMMENT=85, RENAME_MULTILINE_COMMENT=86, RENAME_WS=87, + ON=88, WITH=89, ENRICH_POLICY_NAME=90, ENRICH_LINE_COMMENT=91, ENRICH_MULTILINE_COMMENT=92, + ENRICH_WS=93, ENRICH_FIELD_LINE_COMMENT=94, ENRICH_FIELD_MULTILINE_COMMENT=95, + ENRICH_FIELD_WS=96, LOOKUP_LINE_COMMENT=97, LOOKUP_MULTILINE_COMMENT=98, + LOOKUP_WS=99, LOOKUP_FIELD_LINE_COMMENT=100, LOOKUP_FIELD_MULTILINE_COMMENT=101, + LOOKUP_FIELD_WS=102, MVEXPAND_LINE_COMMENT=103, MVEXPAND_MULTILINE_COMMENT=104, + MVEXPAND_WS=105, INFO=106, SHOW_LINE_COMMENT=107, SHOW_MULTILINE_COMMENT=108, + SHOW_WS=109, FUNCTIONS=110, META_LINE_COMMENT=111, META_MULTILINE_COMMENT=112, + META_WS=113, COLON=114, SETTING=115, SETTING_LINE_COMMENT=116, SETTTING_MULTILINE_COMMENT=117, + SETTING_WS=118, METRICS_LINE_COMMENT=119, METRICS_MULTILINE_COMMENT=120, + METRICS_WS=121, CLOSING_METRICS_LINE_COMMENT=122, CLOSING_METRICS_MULTILINE_COMMENT=123, + CLOSING_METRICS_WS=124; public static final int EXPLAIN_MODE=1, EXPRESSION_MODE=2, FROM_MODE=3, PROJECT_MODE=4, RENAME_MODE=5, ENRICH_MODE=6, ENRICH_FIELD_MODE=7, LOOKUP_MODE=8, LOOKUP_FIELD_MODE=9, @@ -72,28 +73,29 @@ public class EsqlBaseLexer extends Lexer { "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", - "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", - "QUOTED_ID", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", - "EXPR_WS", "FROM_PIPE", "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", - "FROM_COMMA", "FROM_ASSIGN", "FROM_QUOTED_STRING", "METADATA", "FROM_INDEX_UNQUOTED_IDENTIFIER", - "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", "FROM_WS", "PROJECT_PIPE", - "PROJECT_DOT", "PROJECT_COMMA", "UNQUOTED_ID_BODY_WITH_PATTERN", "UNQUOTED_ID_PATTERN", - "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", - "RENAME_PIPE", "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT", "AS", "RENAME_ID_PATTERN", - "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ENRICH_PIPE", - "ENRICH_OPENING_BRACKET", "ON", "WITH", "ENRICH_POLICY_NAME_BODY", "ENRICH_POLICY_NAME", - "ENRICH_QUOTED_IDENTIFIER", "ENRICH_MODE_UNQUOTED_VALUE", "ENRICH_LINE_COMMENT", - "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_PIPE", "ENRICH_FIELD_ASSIGN", - "ENRICH_FIELD_COMMA", "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", "ENRICH_FIELD_ID_PATTERN", - "ENRICH_FIELD_QUOTED_IDENTIFIER", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", - "ENRICH_FIELD_WS", "LOOKUP_PIPE", "LOOKUP_COMMA", "LOOKUP_DOT", "LOOKUP_ON", - "LOOKUP_INDEX_UNQUOTED_IDENTIFIER", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT", - "LOOKUP_WS", "LOOKUP_FIELD_PIPE", "LOOKUP_FIELD_COMMA", "LOOKUP_FIELD_DOT", - "LOOKUP_FIELD_ID_PATTERN", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT", - "LOOKUP_FIELD_WS", "MVEXPAND_PIPE", "MVEXPAND_DOT", "MVEXPAND_QUOTED_IDENTIFIER", - "MVEXPAND_UNQUOTED_IDENTIFIER", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", - "MVEXPAND_WS", "SHOW_PIPE", "INFO", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", - "SHOW_WS", "META_PIPE", "FUNCTIONS", "META_LINE_COMMENT", "META_MULTILINE_COMMENT", + "PERCENT", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET", "CLOSING_BRACKET", + "UNQUOTED_IDENTIFIER", "QUOTED_ID", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", + "EXPR_MULTILINE_COMMENT", "EXPR_WS", "FROM_PIPE", "FROM_OPENING_BRACKET", + "FROM_CLOSING_BRACKET", "FROM_COMMA", "FROM_ASSIGN", "FROM_QUOTED_STRING", + "METADATA", "FROM_INDEX_UNQUOTED_IDENTIFIER", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", "UNQUOTED_ID_BODY_WITH_PATTERN", + "UNQUOTED_ID_PATTERN", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", + "PROJECT_WS", "RENAME_PIPE", "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT", + "AS", "RENAME_ID_PATTERN", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ENRICH_PIPE", "ENRICH_OPENING_BRACKET", "ON", "WITH", "ENRICH_POLICY_NAME_BODY", + "ENRICH_POLICY_NAME", "ENRICH_QUOTED_IDENTIFIER", "ENRICH_MODE_UNQUOTED_VALUE", + "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_PIPE", + "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA", "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", + "ENRICH_FIELD_ID_PATTERN", "ENRICH_FIELD_QUOTED_IDENTIFIER", "ENRICH_FIELD_LINE_COMMENT", + "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "LOOKUP_PIPE", "LOOKUP_COMMA", + "LOOKUP_DOT", "LOOKUP_ON", "LOOKUP_INDEX_UNQUOTED_IDENTIFIER", "LOOKUP_LINE_COMMENT", + "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_PIPE", "LOOKUP_FIELD_COMMA", + "LOOKUP_FIELD_DOT", "LOOKUP_FIELD_ID_PATTERN", "LOOKUP_FIELD_LINE_COMMENT", + "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "MVEXPAND_PIPE", + "MVEXPAND_DOT", "MVEXPAND_QUOTED_IDENTIFIER", "MVEXPAND_UNQUOTED_IDENTIFIER", + "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", + "SHOW_PIPE", "INFO", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", "SHOW_WS", + "META_PIPE", "FUNCTIONS", "META_LINE_COMMENT", "META_MULTILINE_COMMENT", "META_WS", "SETTING_CLOSING_BRACKET", "COLON", "SETTING", "SETTING_LINE_COMMENT", "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "METRICS_PIPE", "METRICS_INDEX_UNQUOTED_IDENTIFIER", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT", "METRICS_WS", "CLOSING_METRICS_COMMA", @@ -114,11 +116,11 @@ public class EsqlBaseLexer extends Lexer { "'desc'", "'.'", "'false'", "'first'", "'last'", "'('", "'in'", "'is'", "'like'", "'not'", "'null'", "'nulls'", "'or'", "'?'", "'rlike'", "')'", "'true'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", - "'-'", "'*'", "'/'", "'%'", null, "']'", null, null, null, null, null, - "'metadata'", null, null, null, null, null, null, null, "'as'", null, - null, null, "'on'", "'with'", null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, "'info'", null, - null, null, "'functions'", null, null, null, "':'" + "'-'", "'*'", "'/'", "'%'", null, null, "']'", null, null, null, null, + null, "'metadata'", null, null, null, null, null, null, null, "'as'", + null, null, null, "'on'", "'with'", null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, "'info'", + null, null, null, "'functions'", null, null, null, "':'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); @@ -133,21 +135,21 @@ public class EsqlBaseLexer extends Lexer { "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", - "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", - "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", - "METADATA", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", "FROM_WS", - "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", - "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", "RENAME_WS", - "ON", "WITH", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", - "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", - "ENRICH_FIELD_WS", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT", - "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT", - "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", - "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", - "SHOW_WS", "FUNCTIONS", "META_LINE_COMMENT", "META_MULTILINE_COMMENT", - "META_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT", "SETTTING_MULTILINE_COMMENT", - "SETTING_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT", "METRICS_WS", - "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT", + "PERCENT", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET", "CLOSING_BRACKET", + "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", + "EXPR_WS", "METADATA", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", + "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT", + "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", + "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "LOOKUP_LINE_COMMENT", + "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", + "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", + "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT", + "SHOW_MULTILINE_COMMENT", "SHOW_WS", "FUNCTIONS", "META_LINE_COMMENT", + "META_MULTILINE_COMMENT", "META_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT", + "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT", + "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT", "CLOSING_METRICS_WS" }; } @@ -211,7 +213,7 @@ public class EsqlBaseLexer extends Lexer { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\u0004\u0000{\u057c\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+ + "\u0004\u0000|\u058e\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+ "\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+ "\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+ "\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+ @@ -265,58 +267,58 @@ public class EsqlBaseLexer extends Lexer { "\u0002\u00b4\u0007\u00b4\u0002\u00b5\u0007\u00b5\u0002\u00b6\u0007\u00b6"+ "\u0002\u00b7\u0007\u00b7\u0002\u00b8\u0007\u00b8\u0002\u00b9\u0007\u00b9"+ "\u0002\u00ba\u0007\u00ba\u0002\u00bb\u0007\u00bb\u0002\u00bc\u0007\u00bc"+ + "\u0002\u00bd\u0007\u00bd\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+ "\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+ - "\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+ - "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+ - "\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ - "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004"+ "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ - "\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ - "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+ + "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007"+ "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+ - "\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001"+ - "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+ - "\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001"+ - "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001"+ - "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ - "\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ - "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+ - "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010"+ - "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011"+ - "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+ - "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+ - "\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+ - "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0004\u0014"+ - "\u0235\b\u0014\u000b\u0014\f\u0014\u0236\u0001\u0014\u0001\u0014\u0001"+ - "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0005\u0015\u023f\b\u0015\n"+ - "\u0015\f\u0015\u0242\t\u0015\u0001\u0015\u0003\u0015\u0245\b\u0015\u0001"+ - "\u0015\u0003\u0015\u0248\b\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001"+ - "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u0251\b\u0016\n"+ - "\u0016\f\u0016\u0254\t\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ - "\u0016\u0001\u0016\u0001\u0017\u0004\u0017\u025c\b\u0017\u000b\u0017\f"+ - "\u0017\u025d\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018"+ - "\u0003\u0018\u0265\b\u0018\u0001\u0019\u0004\u0019\u0268\b\u0019\u000b"+ - "\u0019\f\u0019\u0269\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001"+ - "\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+ - "\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001"+ - "\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001"+ - "\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001!\u0001"+ - "!\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001$\u0003$\u0291\b$"+ - "\u0001$\u0004$\u0294\b$\u000b$\f$\u0295\u0001%\u0001%\u0001&\u0001&\u0001"+ - "\'\u0001\'\u0001\'\u0003\'\u029f\b\'\u0001(\u0001(\u0001)\u0001)\u0001"+ - ")\u0003)\u02a6\b)\u0001*\u0001*\u0001*\u0005*\u02ab\b*\n*\f*\u02ae\t*"+ - "\u0001*\u0001*\u0001*\u0001*\u0001*\u0001*\u0005*\u02b6\b*\n*\f*\u02b9"+ - "\t*\u0001*\u0001*\u0001*\u0001*\u0001*\u0003*\u02c0\b*\u0001*\u0003*\u02c3"+ - "\b*\u0003*\u02c5\b*\u0001+\u0004+\u02c8\b+\u000b+\f+\u02c9\u0001,\u0004"+ - ",\u02cd\b,\u000b,\f,\u02ce\u0001,\u0001,\u0005,\u02d3\b,\n,\f,\u02d6\t"+ - ",\u0001,\u0001,\u0004,\u02da\b,\u000b,\f,\u02db\u0001,\u0004,\u02df\b"+ - ",\u000b,\f,\u02e0\u0001,\u0001,\u0005,\u02e5\b,\n,\f,\u02e8\t,\u0003,"+ - "\u02ea\b,\u0001,\u0001,\u0001,\u0001,\u0004,\u02f0\b,\u000b,\f,\u02f1"+ - "\u0001,\u0001,\u0003,\u02f6\b,\u0001-\u0001-\u0001-\u0001.\u0001.\u0001"+ + "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ + "\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+ + "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001"+ + "\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\u000b"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+ + "\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ + "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e"+ + "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ + "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f"+ + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010"+ + "\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+ + "\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+ + "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013"+ + "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+ + "\u0001\u0014\u0004\u0014\u0237\b\u0014\u000b\u0014\f\u0014\u0238\u0001"+ + "\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0005"+ + "\u0015\u0241\b\u0015\n\u0015\f\u0015\u0244\t\u0015\u0001\u0015\u0003\u0015"+ + "\u0247\b\u0015\u0001\u0015\u0003\u0015\u024a\b\u0015\u0001\u0015\u0001"+ + "\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005"+ + "\u0016\u0253\b\u0016\n\u0016\f\u0016\u0256\t\u0016\u0001\u0016\u0001\u0016"+ + "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0004\u0017\u025e\b\u0017"+ + "\u000b\u0017\f\u0017\u025f\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018"+ + "\u0001\u0018\u0003\u0018\u0267\b\u0018\u0001\u0019\u0004\u0019\u026a\b"+ + "\u0019\u000b\u0019\f\u0019\u026b\u0001\u001a\u0001\u001a\u0001\u001a\u0001"+ + "\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+ + "\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001"+ + "\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001"+ + "\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001"+ + "!\u0001!\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001$\u0003$\u0293"+ + "\b$\u0001$\u0004$\u0296\b$\u000b$\f$\u0297\u0001%\u0001%\u0001&\u0001"+ + "&\u0001\'\u0001\'\u0001\'\u0003\'\u02a1\b\'\u0001(\u0001(\u0001)\u0001"+ + ")\u0001)\u0003)\u02a8\b)\u0001*\u0001*\u0001*\u0005*\u02ad\b*\n*\f*\u02b0"+ + "\t*\u0001*\u0001*\u0001*\u0001*\u0001*\u0001*\u0005*\u02b8\b*\n*\f*\u02bb"+ + "\t*\u0001*\u0001*\u0001*\u0001*\u0001*\u0003*\u02c2\b*\u0001*\u0003*\u02c5"+ + "\b*\u0003*\u02c7\b*\u0001+\u0004+\u02ca\b+\u000b+\f+\u02cb\u0001,\u0004"+ + ",\u02cf\b,\u000b,\f,\u02d0\u0001,\u0001,\u0005,\u02d5\b,\n,\f,\u02d8\t"+ + ",\u0001,\u0001,\u0004,\u02dc\b,\u000b,\f,\u02dd\u0001,\u0004,\u02e1\b"+ + ",\u000b,\f,\u02e2\u0001,\u0001,\u0005,\u02e7\b,\n,\f,\u02ea\t,\u0003,"+ + "\u02ec\b,\u0001,\u0001,\u0001,\u0001,\u0004,\u02f2\b,\u000b,\f,\u02f3"+ + "\u0001,\u0001,\u0003,\u02f8\b,\u0001-\u0001-\u0001-\u0001.\u0001.\u0001"+ ".\u0001.\u0001/\u0001/\u0001/\u0001/\u00010\u00010\u00011\u00011\u0001"+ "1\u00012\u00012\u00013\u00013\u00013\u00013\u00013\u00014\u00014\u0001"+ "5\u00015\u00015\u00015\u00015\u00015\u00016\u00016\u00016\u00016\u0001"+ @@ -328,782 +330,794 @@ public class EsqlBaseLexer extends Lexer { "C\u0001C\u0001C\u0001D\u0001D\u0001D\u0001E\u0001E\u0001E\u0001F\u0001"+ "F\u0001F\u0001G\u0001G\u0001H\u0001H\u0001H\u0001I\u0001I\u0001J\u0001"+ "J\u0001J\u0001K\u0001K\u0001L\u0001L\u0001M\u0001M\u0001N\u0001N\u0001"+ - "O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001"+ - "Q\u0001Q\u0001R\u0001R\u0005R\u0379\bR\nR\fR\u037c\tR\u0001R\u0001R\u0003"+ - "R\u0380\bR\u0001R\u0004R\u0383\bR\u000bR\fR\u0384\u0003R\u0387\bR\u0001"+ - "S\u0001S\u0004S\u038b\bS\u000bS\fS\u038c\u0001S\u0001S\u0001T\u0001T\u0001"+ - "U\u0001U\u0001U\u0001U\u0001V\u0001V\u0001V\u0001V\u0001W\u0001W\u0001"+ - "W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001X\u0001Y\u0001Y\u0001Y\u0001"+ - "Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001[\u0001[\u0001\\\u0001"+ - "\\\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001]\u0001^\u0001^\u0001^\u0001"+ - "^\u0001^\u0001^\u0001^\u0001^\u0001^\u0001_\u0001_\u0001_\u0001_\u0001"+ - "`\u0001`\u0001`\u0001`\u0001a\u0001a\u0001a\u0001a\u0001b\u0001b\u0001"+ - "b\u0001b\u0001c\u0001c\u0001c\u0001c\u0001c\u0001d\u0001d\u0001d\u0001"+ - "d\u0001e\u0001e\u0001e\u0001e\u0001f\u0001f\u0001f\u0001f\u0003f\u03e2"+ - "\bf\u0001g\u0001g\u0003g\u03e6\bg\u0001g\u0005g\u03e9\bg\ng\fg\u03ec\t"+ - "g\u0001g\u0001g\u0003g\u03f0\bg\u0001g\u0004g\u03f3\bg\u000bg\fg\u03f4"+ - "\u0003g\u03f7\bg\u0001h\u0001h\u0004h\u03fb\bh\u000bh\fh\u03fc\u0001i"+ - "\u0001i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001j\u0001k\u0001k\u0001"+ - "k\u0001k\u0001l\u0001l\u0001l\u0001l\u0001l\u0001m\u0001m\u0001m\u0001"+ - "m\u0001n\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001o\u0001p\u0001"+ - "p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001r\u0001r\u0001r\u0001r\u0001"+ - "s\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001t\u0001u\u0001u\u0001"+ - "u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001v\u0001v\u0001w\u0001w\u0001"+ - "w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001x\u0001x\u0001x\u0001x\u0001"+ - "y\u0001y\u0001z\u0004z\u0448\bz\u000bz\fz\u0449\u0001z\u0001z\u0003z\u044e"+ - "\bz\u0001z\u0004z\u0451\bz\u000bz\fz\u0452\u0001{\u0001{\u0001{\u0001"+ - "{\u0001|\u0001|\u0001|\u0001|\u0001}\u0001}\u0001}\u0001}\u0001~\u0001"+ - "~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0001\u007f\u0001\u007f\u0001"+ - "\u0080\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0080\u0001"+ - "\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0082\u0001\u0082\u0001"+ - "\u0082\u0001\u0082\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0083\u0001"+ - "\u0084\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0085\u0001\u0085\u0001"+ - "\u0085\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086\u0001"+ - "\u0087\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0088\u0001\u0088\u0001"+ - "\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089\u0001\u0089\u0001"+ - "\u008a\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008b\u0001"+ - "\u008b\u0001\u008b\u0001\u008b\u0001\u008c\u0001\u008c\u0001\u008c\u0001"+ - "\u008c\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001"+ - "\u008e\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008f\u0001\u008f\u0001"+ - "\u008f\u0001\u008f\u0001\u0090\u0001\u0090\u0001\u0090\u0001\u0090\u0001"+ - "\u0091\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0092\u0001\u0092\u0001"+ - "\u0092\u0001\u0092\u0001\u0092\u0001\u0092\u0001\u0093\u0001\u0093\u0001"+ - "\u0093\u0001\u0093\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0094\u0001"+ - "\u0095\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0096\u0001\u0096\u0001"+ - "\u0096\u0001\u0096\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0097\u0001"+ - "\u0098\u0001\u0098\u0001\u0098\u0001\u0098\u0001\u0099\u0001\u0099\u0001"+ + "O\u0001O\u0001P\u0001P\u0001P\u0005P\u0372\bP\nP\fP\u0375\tP\u0001P\u0001"+ + "P\u0004P\u0379\bP\u000bP\fP\u037a\u0003P\u037d\bP\u0001Q\u0001Q\u0001"+ + "Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001R\u0001R\u0001S\u0001S\u0005"+ + "S\u038b\bS\nS\fS\u038e\tS\u0001S\u0001S\u0003S\u0392\bS\u0001S\u0004S"+ + "\u0395\bS\u000bS\fS\u0396\u0003S\u0399\bS\u0001T\u0001T\u0004T\u039d\b"+ + "T\u000bT\fT\u039e\u0001T\u0001T\u0001U\u0001U\u0001V\u0001V\u0001V\u0001"+ + "V\u0001W\u0001W\u0001W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001Y\u0001"+ + "Y\u0001Y\u0001Y\u0001Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001"+ + "[\u0001[\u0001\\\u0001\\\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001]\u0001"+ + "^\u0001^\u0001^\u0001^\u0001_\u0001_\u0001_\u0001_\u0001_\u0001_\u0001"+ + "_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001`\u0001a\u0001a\u0001a\u0001"+ + "a\u0001b\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001c\u0001d\u0001"+ + "d\u0001d\u0001d\u0001d\u0001e\u0001e\u0001e\u0001e\u0001f\u0001f\u0001"+ + "f\u0001f\u0001g\u0001g\u0001g\u0001g\u0003g\u03f4\bg\u0001h\u0001h\u0003"+ + "h\u03f8\bh\u0001h\u0005h\u03fb\bh\nh\fh\u03fe\th\u0001h\u0001h\u0003h"+ + "\u0402\bh\u0001h\u0004h\u0405\bh\u000bh\fh\u0406\u0003h\u0409\bh\u0001"+ + "i\u0001i\u0004i\u040d\bi\u000bi\fi\u040e\u0001j\u0001j\u0001j\u0001j\u0001"+ + "k\u0001k\u0001k\u0001k\u0001l\u0001l\u0001l\u0001l\u0001m\u0001m\u0001"+ + "m\u0001m\u0001m\u0001n\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001"+ + "o\u0001p\u0001p\u0001p\u0001p\u0001q\u0001q\u0001q\u0001r\u0001r\u0001"+ + "r\u0001r\u0001s\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001t\u0001"+ + "u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001v\u0001v\u0001w\u0001"+ + "w\u0001w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001x\u0001x\u0001y\u0001"+ + "y\u0001y\u0001y\u0001y\u0001y\u0001y\u0001z\u0001z\u0001{\u0004{\u045a"+ + "\b{\u000b{\f{\u045b\u0001{\u0001{\u0003{\u0460\b{\u0001{\u0004{\u0463"+ + "\b{\u000b{\f{\u0464\u0001|\u0001|\u0001|\u0001|\u0001}\u0001}\u0001}\u0001"+ + "}\u0001~\u0001~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0001\u007f\u0001"+ + "\u007f\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0081\u0001"+ + "\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0082\u0001"+ + "\u0082\u0001\u0082\u0001\u0082\u0001\u0083\u0001\u0083\u0001\u0083\u0001"+ + "\u0083\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0085\u0001"+ + "\u0085\u0001\u0085\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0086\u0001"+ + "\u0086\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0088\u0001"+ + "\u0088\u0001\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089\u0001"+ + "\u0089\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008b\u0001"+ + "\u008b\u0001\u008b\u0001\u008b\u0001\u008b\u0001\u008c\u0001\u008c\u0001"+ + "\u008c\u0001\u008c\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001"+ + "\u008e\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008f\u0001"+ + "\u008f\u0001\u008f\u0001\u008f\u0001\u0090\u0001\u0090\u0001\u0090\u0001"+ + "\u0090\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0092\u0001"+ + "\u0092\u0001\u0092\u0001\u0092\u0001\u0093\u0001\u0093\u0001\u0093\u0001"+ + "\u0093\u0001\u0093\u0001\u0093\u0001\u0094\u0001\u0094\u0001\u0094\u0001"+ + "\u0094\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0096\u0001"+ + "\u0096\u0001\u0096\u0001\u0096\u0001\u0097\u0001\u0097\u0001\u0097\u0001"+ + "\u0097\u0001\u0098\u0001\u0098\u0001\u0098\u0001\u0098\u0001\u0099\u0001"+ "\u0099\u0001\u0099\u0001\u0099\u0001\u009a\u0001\u009a\u0001\u009a\u0001"+ - "\u009a\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009c\u0001"+ - "\u009c\u0001\u009c\u0001\u009c\u0001\u009d\u0001\u009d\u0001\u009d\u0001"+ - "\u009d\u0001\u009e\u0001\u009e\u0001\u009e\u0001\u009e\u0001\u009f\u0001"+ - "\u009f\u0001\u009f\u0001\u009f\u0001\u00a0\u0001\u00a0\u0001\u00a0\u0001"+ + "\u009a\u0001\u009a\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009b\u0001"+ + "\u009c\u0001\u009c\u0001\u009c\u0001\u009c\u0001\u009d\u0001\u009d\u0001"+ + "\u009d\u0001\u009d\u0001\u009e\u0001\u009e\u0001\u009e\u0001\u009e\u0001"+ + "\u009f\u0001\u009f\u0001\u009f\u0001\u009f\u0001\u00a0\u0001\u00a0\u0001"+ "\u00a0\u0001\u00a0\u0001\u00a1\u0001\u00a1\u0001\u00a1\u0001\u00a1\u0001"+ - "\u00a1\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a3\u0001"+ - "\u00a3\u0001\u00a3\u0001\u00a3\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001"+ - "\u00a4\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001"+ - "\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001"+ - "\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a7\u0001\u00a7\u0001"+ - "\u00a7\u0001\u00a7\u0001\u00a8\u0001\u00a8\u0001\u00a8\u0001\u00a8\u0001"+ - "\u00a9\u0001\u00a9\u0001\u00a9\u0001\u00a9\u0001\u00aa\u0001\u00aa\u0001"+ - "\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00ab\u0001\u00ab\u0001\u00ac\u0001"+ - "\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0004\u00ac\u052d\b\u00ac\u000b"+ - "\u00ac\f\u00ac\u052e\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001"+ - "\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00af\u0001\u00af\u0001"+ - "\u00af\u0001\u00af\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001"+ - "\u00b0\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001"+ - "\u00b1\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b3\u0001"+ - "\u00b3\u0001\u00b3\u0001\u00b3\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001"+ - "\u00b4\u0001\u00b5\u0001\u00b5\u0001\u00b5\u0001\u00b5\u0001\u00b5\u0001"+ - "\u00b5\u0001\u00b6\u0001\u00b6\u0001\u00b6\u0001\u00b6\u0001\u00b7\u0001"+ - "\u00b7\u0001\u00b7\u0001\u00b7\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001"+ - "\u00b8\u0001\u00b9\u0001\u00b9\u0001\u00b9\u0001\u00b9\u0001\u00b9\u0001"+ - "\u00b9\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001"+ - "\u00ba\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001"+ - "\u00bb\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0002"+ - "\u0252\u02b7\u0000\u00bd\u0010\u0001\u0012\u0002\u0014\u0003\u0016\u0004"+ - "\u0018\u0005\u001a\u0006\u001c\u0007\u001e\b \t\"\n$\u000b&\f(\r*\u000e"+ - ",\u000f.\u00100\u00112\u00124\u00136\u00148\u0015:\u0016<\u0017>\u0018"+ - "@\u0000B\u0019D\u0000F\u0000H\u001aJ\u001bL\u001cN\u001dP\u0000R\u0000"+ - "T\u0000V\u0000X\u0000Z\u0000\\\u0000^\u0000`\u0000b\u0000d\u001ef\u001f"+ - "h j!l\"n#p$r%t&v\'x(z)|*~+\u0080,\u0082-\u0084.\u0086/\u00880\u008a1\u008c"+ + "\u00a1\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001"+ + "\u00a3\u0001\u00a3\u0001\u00a3\u0001\u00a3\u0001\u00a4\u0001\u00a4\u0001"+ + "\u00a4\u0001\u00a4\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001"+ + "\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a7\u0001"+ + "\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001"+ + "\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a8\u0001\u00a8\u0001\u00a8\u0001"+ + "\u00a8\u0001\u00a9\u0001\u00a9\u0001\u00a9\u0001\u00a9\u0001\u00aa\u0001"+ + "\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00ab\u0001\u00ab\u0001\u00ab\u0001"+ + "\u00ab\u0001\u00ab\u0001\u00ac\u0001\u00ac\u0001\u00ad\u0001\u00ad\u0001"+ + "\u00ad\u0001\u00ad\u0001\u00ad\u0004\u00ad\u053f\b\u00ad\u000b\u00ad\f"+ + "\u00ad\u0540\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00af"+ + "\u0001\u00af\u0001\u00af\u0001\u00af\u0001\u00b0\u0001\u00b0\u0001\u00b0"+ + "\u0001\u00b0\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1"+ + "\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b2"+ + "\u0001\u00b3\u0001\u00b3\u0001\u00b3\u0001\u00b3\u0001\u00b4\u0001\u00b4"+ + "\u0001\u00b4\u0001\u00b4\u0001\u00b5\u0001\u00b5\u0001\u00b5\u0001\u00b5"+ + "\u0001\u00b6\u0001\u00b6\u0001\u00b6\u0001\u00b6\u0001\u00b6\u0001\u00b6"+ + "\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001\u00b8\u0001\u00b8"+ + "\u0001\u00b8\u0001\u00b8\u0001\u00b9\u0001\u00b9\u0001\u00b9\u0001\u00b9"+ + "\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001\u00ba"+ + "\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb"+ + "\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc"+ + "\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0002\u0254"+ + "\u02b9\u0000\u00be\u0010\u0001\u0012\u0002\u0014\u0003\u0016\u0004\u0018"+ + "\u0005\u001a\u0006\u001c\u0007\u001e\b \t\"\n$\u000b&\f(\r*\u000e,\u000f"+ + ".\u00100\u00112\u00124\u00136\u00148\u0015:\u0016<\u0017>\u0018@\u0000"+ + "B\u0019D\u0000F\u0000H\u001aJ\u001bL\u001cN\u001dP\u0000R\u0000T\u0000"+ + "V\u0000X\u0000Z\u0000\\\u0000^\u0000`\u0000b\u0000d\u001ef\u001fh j!l"+ + "\"n#p$r%t&v\'x(z)|*~+\u0080,\u0082-\u0084.\u0086/\u00880\u008a1\u008c"+ "2\u008e3\u00904\u00925\u00946\u00967\u00988\u009a9\u009c:\u009e;\u00a0"+ "<\u00a2=\u00a4>\u00a6?\u00a8@\u00aaA\u00acB\u00aeC\u00b0D\u00b2E\u00b4"+ - "F\u00b6\u0000\u00b8G\u00baH\u00bcI\u00beJ\u00c0\u0000\u00c2\u0000\u00c4"+ - "\u0000\u00c6\u0000\u00c8\u0000\u00ca\u0000\u00ccK\u00ce\u0000\u00d0L\u00d2"+ - "M\u00d4N\u00d6\u0000\u00d8\u0000\u00da\u0000\u00dc\u0000\u00de\u0000\u00e0"+ - "O\u00e2P\u00e4Q\u00e6R\u00e8\u0000\u00ea\u0000\u00ec\u0000\u00ee\u0000"+ - "\u00f0S\u00f2\u0000\u00f4T\u00f6U\u00f8V\u00fa\u0000\u00fc\u0000\u00fe"+ - "W\u0100X\u0102\u0000\u0104Y\u0106\u0000\u0108\u0000\u010aZ\u010c[\u010e"+ - "\\\u0110\u0000\u0112\u0000\u0114\u0000\u0116\u0000\u0118\u0000\u011a\u0000"+ - "\u011c\u0000\u011e]\u0120^\u0122_\u0124\u0000\u0126\u0000\u0128\u0000"+ - "\u012a\u0000\u012c\u0000\u012e`\u0130a\u0132b\u0134\u0000\u0136\u0000"+ - "\u0138\u0000\u013a\u0000\u013cc\u013ed\u0140e\u0142\u0000\u0144\u0000"+ - "\u0146\u0000\u0148\u0000\u014af\u014cg\u014eh\u0150\u0000\u0152i\u0154"+ - "j\u0156k\u0158l\u015a\u0000\u015cm\u015en\u0160o\u0162p\u0164\u0000\u0166"+ - "q\u0168r\u016as\u016ct\u016eu\u0170\u0000\u0172\u0000\u0174v\u0176w\u0178"+ - "x\u017a\u0000\u017cy\u017ez\u0180{\u0182\u0000\u0184\u0000\u0186\u0000"+ - "\u0188\u0000\u0010\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t"+ - "\n\u000b\f\r\u000e\u000f\r\u0006\u0000\t\n\r\r //[[]]\u0002\u0000\n\n"+ - "\r\r\u0003\u0000\t\n\r\r \n\u0000\t\n\r\r ,,//==[[]]``||\u0002\u0000"+ - "**//\u0001\u000009\u0002\u0000AZaz\u0005\u0000\"\"\\\\nnrrtt\u0004\u0000"+ - "\n\n\r\r\"\"\\\\\u0002\u0000EEee\u0002\u0000++--\u0001\u0000``\u000b\u0000"+ - "\t\n\r\r \"#,,//::<<>?\\\\||\u0593\u0000\u0010\u0001\u0000\u0000\u0000"+ - "\u0000\u0012\u0001\u0000\u0000\u0000\u0000\u0014\u0001\u0000\u0000\u0000"+ - "\u0000\u0016\u0001\u0000\u0000\u0000\u0000\u0018\u0001\u0000\u0000\u0000"+ - "\u0000\u001a\u0001\u0000\u0000\u0000\u0000\u001c\u0001\u0000\u0000\u0000"+ - "\u0000\u001e\u0001\u0000\u0000\u0000\u0000 \u0001\u0000\u0000\u0000\u0000"+ - "\"\u0001\u0000\u0000\u0000\u0000$\u0001\u0000\u0000\u0000\u0000&\u0001"+ - "\u0000\u0000\u0000\u0000(\u0001\u0000\u0000\u0000\u0000*\u0001\u0000\u0000"+ - "\u0000\u0000,\u0001\u0000\u0000\u0000\u0000.\u0001\u0000\u0000\u0000\u0000"+ - "0\u0001\u0000\u0000\u0000\u00002\u0001\u0000\u0000\u0000\u00004\u0001"+ - "\u0000\u0000\u0000\u00006\u0001\u0000\u0000\u0000\u00008\u0001\u0000\u0000"+ - "\u0000\u0000:\u0001\u0000\u0000\u0000\u0000<\u0001\u0000\u0000\u0000\u0000"+ - ">\u0001\u0000\u0000\u0000\u0000B\u0001\u0000\u0000\u0000\u0001D\u0001"+ - "\u0000\u0000\u0000\u0001F\u0001\u0000\u0000\u0000\u0001H\u0001\u0000\u0000"+ - "\u0000\u0001J\u0001\u0000\u0000\u0000\u0001L\u0001\u0000\u0000\u0000\u0002"+ - "N\u0001\u0000\u0000\u0000\u0002d\u0001\u0000\u0000\u0000\u0002f\u0001"+ - "\u0000\u0000\u0000\u0002h\u0001\u0000\u0000\u0000\u0002j\u0001\u0000\u0000"+ - "\u0000\u0002l\u0001\u0000\u0000\u0000\u0002n\u0001\u0000\u0000\u0000\u0002"+ - "p\u0001\u0000\u0000\u0000\u0002r\u0001\u0000\u0000\u0000\u0002t\u0001"+ - "\u0000\u0000\u0000\u0002v\u0001\u0000\u0000\u0000\u0002x\u0001\u0000\u0000"+ - "\u0000\u0002z\u0001\u0000\u0000\u0000\u0002|\u0001\u0000\u0000\u0000\u0002"+ - "~\u0001\u0000\u0000\u0000\u0002\u0080\u0001\u0000\u0000\u0000\u0002\u0082"+ - "\u0001\u0000\u0000\u0000\u0002\u0084\u0001\u0000\u0000\u0000\u0002\u0086"+ - "\u0001\u0000\u0000\u0000\u0002\u0088\u0001\u0000\u0000\u0000\u0002\u008a"+ - "\u0001\u0000\u0000\u0000\u0002\u008c\u0001\u0000\u0000\u0000\u0002\u008e"+ - "\u0001\u0000\u0000\u0000\u0002\u0090\u0001\u0000\u0000\u0000\u0002\u0092"+ - "\u0001\u0000\u0000\u0000\u0002\u0094\u0001\u0000\u0000\u0000\u0002\u0096"+ - "\u0001\u0000\u0000\u0000\u0002\u0098\u0001\u0000\u0000\u0000\u0002\u009a"+ - "\u0001\u0000\u0000\u0000\u0002\u009c\u0001\u0000\u0000\u0000\u0002\u009e"+ - "\u0001\u0000\u0000\u0000\u0002\u00a0\u0001\u0000\u0000\u0000\u0002\u00a2"+ - "\u0001\u0000\u0000\u0000\u0002\u00a4\u0001\u0000\u0000\u0000\u0002\u00a6"+ - "\u0001\u0000\u0000\u0000\u0002\u00a8\u0001\u0000\u0000\u0000\u0002\u00aa"+ - "\u0001\u0000\u0000\u0000\u0002\u00ac\u0001\u0000\u0000\u0000\u0002\u00ae"+ - "\u0001\u0000\u0000\u0000\u0002\u00b0\u0001\u0000\u0000\u0000\u0002\u00b2"+ - "\u0001\u0000\u0000\u0000\u0002\u00b4\u0001\u0000\u0000\u0000\u0002\u00b8"+ - "\u0001\u0000\u0000\u0000\u0002\u00ba\u0001\u0000\u0000\u0000\u0002\u00bc"+ - "\u0001\u0000\u0000\u0000\u0002\u00be\u0001\u0000\u0000\u0000\u0003\u00c0"+ - "\u0001\u0000\u0000\u0000\u0003\u00c2\u0001\u0000\u0000\u0000\u0003\u00c4"+ - "\u0001\u0000\u0000\u0000\u0003\u00c6\u0001\u0000\u0000\u0000\u0003\u00c8"+ - "\u0001\u0000\u0000\u0000\u0003\u00ca\u0001\u0000\u0000\u0000\u0003\u00cc"+ - "\u0001\u0000\u0000\u0000\u0003\u00ce\u0001\u0000\u0000\u0000\u0003\u00d0"+ - "\u0001\u0000\u0000\u0000\u0003\u00d2\u0001\u0000\u0000\u0000\u0003\u00d4"+ - "\u0001\u0000\u0000\u0000\u0004\u00d6\u0001\u0000\u0000\u0000\u0004\u00d8"+ - "\u0001\u0000\u0000\u0000\u0004\u00da\u0001\u0000\u0000\u0000\u0004\u00e0"+ - "\u0001\u0000\u0000\u0000\u0004\u00e2\u0001\u0000\u0000\u0000\u0004\u00e4"+ - "\u0001\u0000\u0000\u0000\u0004\u00e6\u0001\u0000\u0000\u0000\u0005\u00e8"+ - "\u0001\u0000\u0000\u0000\u0005\u00ea\u0001\u0000\u0000\u0000\u0005\u00ec"+ - "\u0001\u0000\u0000\u0000\u0005\u00ee\u0001\u0000\u0000\u0000\u0005\u00f0"+ - "\u0001\u0000\u0000\u0000\u0005\u00f2\u0001\u0000\u0000\u0000\u0005\u00f4"+ - "\u0001\u0000\u0000\u0000\u0005\u00f6\u0001\u0000\u0000\u0000\u0005\u00f8"+ - "\u0001\u0000\u0000\u0000\u0006\u00fa\u0001\u0000\u0000\u0000\u0006\u00fc"+ - "\u0001\u0000\u0000\u0000\u0006\u00fe\u0001\u0000\u0000\u0000\u0006\u0100"+ - "\u0001\u0000\u0000\u0000\u0006\u0104\u0001\u0000\u0000\u0000\u0006\u0106"+ - "\u0001\u0000\u0000\u0000\u0006\u0108\u0001\u0000\u0000\u0000\u0006\u010a"+ - "\u0001\u0000\u0000\u0000\u0006\u010c\u0001\u0000\u0000\u0000\u0006\u010e"+ - "\u0001\u0000\u0000\u0000\u0007\u0110\u0001\u0000\u0000\u0000\u0007\u0112"+ - "\u0001\u0000\u0000\u0000\u0007\u0114\u0001\u0000\u0000\u0000\u0007\u0116"+ - "\u0001\u0000\u0000\u0000\u0007\u0118\u0001\u0000\u0000\u0000\u0007\u011a"+ - "\u0001\u0000\u0000\u0000\u0007\u011c\u0001\u0000\u0000\u0000\u0007\u011e"+ - "\u0001\u0000\u0000\u0000\u0007\u0120\u0001\u0000\u0000\u0000\u0007\u0122"+ - "\u0001\u0000\u0000\u0000\b\u0124\u0001\u0000\u0000\u0000\b\u0126\u0001"+ - "\u0000\u0000\u0000\b\u0128\u0001\u0000\u0000\u0000\b\u012a\u0001\u0000"+ - "\u0000\u0000\b\u012c\u0001\u0000\u0000\u0000\b\u012e\u0001\u0000\u0000"+ - "\u0000\b\u0130\u0001\u0000\u0000\u0000\b\u0132\u0001\u0000\u0000\u0000"+ - "\t\u0134\u0001\u0000\u0000\u0000\t\u0136\u0001\u0000\u0000\u0000\t\u0138"+ - "\u0001\u0000\u0000\u0000\t\u013a\u0001\u0000\u0000\u0000\t\u013c\u0001"+ - "\u0000\u0000\u0000\t\u013e\u0001\u0000\u0000\u0000\t\u0140\u0001\u0000"+ - "\u0000\u0000\n\u0142\u0001\u0000\u0000\u0000\n\u0144\u0001\u0000\u0000"+ - "\u0000\n\u0146\u0001\u0000\u0000\u0000\n\u0148\u0001\u0000\u0000\u0000"+ - "\n\u014a\u0001\u0000\u0000\u0000\n\u014c\u0001\u0000\u0000\u0000\n\u014e"+ - "\u0001\u0000\u0000\u0000\u000b\u0150\u0001\u0000\u0000\u0000\u000b\u0152"+ - "\u0001\u0000\u0000\u0000\u000b\u0154\u0001\u0000\u0000\u0000\u000b\u0156"+ - "\u0001\u0000\u0000\u0000\u000b\u0158\u0001\u0000\u0000\u0000\f\u015a\u0001"+ - "\u0000\u0000\u0000\f\u015c\u0001\u0000\u0000\u0000\f\u015e\u0001\u0000"+ - "\u0000\u0000\f\u0160\u0001\u0000\u0000\u0000\f\u0162\u0001\u0000\u0000"+ - "\u0000\r\u0164\u0001\u0000\u0000\u0000\r\u0166\u0001\u0000\u0000\u0000"+ - "\r\u0168\u0001\u0000\u0000\u0000\r\u016a\u0001\u0000\u0000\u0000\r\u016c"+ - "\u0001\u0000\u0000\u0000\r\u016e\u0001\u0000\u0000\u0000\u000e\u0170\u0001"+ - "\u0000\u0000\u0000\u000e\u0172\u0001\u0000\u0000\u0000\u000e\u0174\u0001"+ - "\u0000\u0000\u0000\u000e\u0176\u0001\u0000\u0000\u0000\u000e\u0178\u0001"+ - "\u0000\u0000\u0000\u000f\u017a\u0001\u0000\u0000\u0000\u000f\u017c\u0001"+ - "\u0000\u0000\u0000\u000f\u017e\u0001\u0000\u0000\u0000\u000f\u0180\u0001"+ - "\u0000\u0000\u0000\u000f\u0182\u0001\u0000\u0000\u0000\u000f\u0184\u0001"+ - "\u0000\u0000\u0000\u000f\u0186\u0001\u0000\u0000\u0000\u000f\u0188\u0001"+ - "\u0000\u0000\u0000\u0010\u018a\u0001\u0000\u0000\u0000\u0012\u0194\u0001"+ - "\u0000\u0000\u0000\u0014\u019b\u0001\u0000\u0000\u0000\u0016\u01a4\u0001"+ - "\u0000\u0000\u0000\u0018\u01ab\u0001\u0000\u0000\u0000\u001a\u01b5\u0001"+ - "\u0000\u0000\u0000\u001c\u01bc\u0001\u0000\u0000\u0000\u001e\u01c3\u0001"+ - "\u0000\u0000\u0000 \u01d1\u0001\u0000\u0000\u0000\"\u01d8\u0001\u0000"+ - "\u0000\u0000$\u01e0\u0001\u0000\u0000\u0000&\u01e9\u0001\u0000\u0000\u0000"+ - "(\u01f0\u0001\u0000\u0000\u0000*\u01fa\u0001\u0000\u0000\u0000,\u0206"+ - "\u0001\u0000\u0000\u0000.\u020f\u0001\u0000\u0000\u00000\u0215\u0001\u0000"+ - "\u0000\u00002\u021c\u0001\u0000\u0000\u00004\u0223\u0001\u0000\u0000\u0000"+ - "6\u022b\u0001\u0000\u0000\u00008\u0234\u0001\u0000\u0000\u0000:\u023a"+ - "\u0001\u0000\u0000\u0000<\u024b\u0001\u0000\u0000\u0000>\u025b\u0001\u0000"+ - "\u0000\u0000@\u0264\u0001\u0000\u0000\u0000B\u0267\u0001\u0000\u0000\u0000"+ - "D\u026b\u0001\u0000\u0000\u0000F\u0270\u0001\u0000\u0000\u0000H\u0275"+ - "\u0001\u0000\u0000\u0000J\u0279\u0001\u0000\u0000\u0000L\u027d\u0001\u0000"+ - "\u0000\u0000N\u0281\u0001\u0000\u0000\u0000P\u0285\u0001\u0000\u0000\u0000"+ - "R\u0287\u0001\u0000\u0000\u0000T\u0289\u0001\u0000\u0000\u0000V\u028c"+ - "\u0001\u0000\u0000\u0000X\u028e\u0001\u0000\u0000\u0000Z\u0297\u0001\u0000"+ - "\u0000\u0000\\\u0299\u0001\u0000\u0000\u0000^\u029e\u0001\u0000\u0000"+ - "\u0000`\u02a0\u0001\u0000\u0000\u0000b\u02a5\u0001\u0000\u0000\u0000d"+ - "\u02c4\u0001\u0000\u0000\u0000f\u02c7\u0001\u0000\u0000\u0000h\u02f5\u0001"+ - "\u0000\u0000\u0000j\u02f7\u0001\u0000\u0000\u0000l\u02fa\u0001\u0000\u0000"+ - "\u0000n\u02fe\u0001\u0000\u0000\u0000p\u0302\u0001\u0000\u0000\u0000r"+ - "\u0304\u0001\u0000\u0000\u0000t\u0307\u0001\u0000\u0000\u0000v\u0309\u0001"+ - "\u0000\u0000\u0000x\u030e\u0001\u0000\u0000\u0000z\u0310\u0001\u0000\u0000"+ - "\u0000|\u0316\u0001\u0000\u0000\u0000~\u031c\u0001\u0000\u0000\u0000\u0080"+ - "\u0321\u0001\u0000\u0000\u0000\u0082\u0323\u0001\u0000\u0000\u0000\u0084"+ - "\u0326\u0001\u0000\u0000\u0000\u0086\u0329\u0001\u0000\u0000\u0000\u0088"+ - "\u032e\u0001\u0000\u0000\u0000\u008a\u0332\u0001\u0000\u0000\u0000\u008c"+ - "\u0337\u0001\u0000\u0000\u0000\u008e\u033d\u0001\u0000\u0000\u0000\u0090"+ - "\u0340\u0001\u0000\u0000\u0000\u0092\u0342\u0001\u0000\u0000\u0000\u0094"+ - "\u0348\u0001\u0000\u0000\u0000\u0096\u034a\u0001\u0000\u0000\u0000\u0098"+ - "\u034f\u0001\u0000\u0000\u0000\u009a\u0352\u0001\u0000\u0000\u0000\u009c"+ - "\u0355\u0001\u0000\u0000\u0000\u009e\u0358\u0001\u0000\u0000\u0000\u00a0"+ - "\u035a\u0001\u0000\u0000\u0000\u00a2\u035d\u0001\u0000\u0000\u0000\u00a4"+ - "\u035f\u0001\u0000\u0000\u0000\u00a6\u0362\u0001\u0000\u0000\u0000\u00a8"+ - "\u0364\u0001\u0000\u0000\u0000\u00aa\u0366\u0001\u0000\u0000\u0000\u00ac"+ - "\u0368\u0001\u0000\u0000\u0000\u00ae\u036a\u0001\u0000\u0000\u0000\u00b0"+ - "\u036c\u0001\u0000\u0000\u0000\u00b2\u0371\u0001\u0000\u0000\u0000\u00b4"+ - "\u0386\u0001\u0000\u0000\u0000\u00b6\u0388\u0001\u0000\u0000\u0000\u00b8"+ - "\u0390\u0001\u0000\u0000\u0000\u00ba\u0392\u0001\u0000\u0000\u0000\u00bc"+ - "\u0396\u0001\u0000\u0000\u0000\u00be\u039a\u0001\u0000\u0000\u0000\u00c0"+ - "\u039e\u0001\u0000\u0000\u0000\u00c2\u03a3\u0001\u0000\u0000\u0000\u00c4"+ - "\u03a7\u0001\u0000\u0000\u0000\u00c6\u03ab\u0001\u0000\u0000\u0000\u00c8"+ - "\u03af\u0001\u0000\u0000\u0000\u00ca\u03b3\u0001\u0000\u0000\u0000\u00cc"+ - "\u03b7\u0001\u0000\u0000\u0000\u00ce\u03c0\u0001\u0000\u0000\u0000\u00d0"+ - "\u03c4\u0001\u0000\u0000\u0000\u00d2\u03c8\u0001\u0000\u0000\u0000\u00d4"+ - "\u03cc\u0001\u0000\u0000\u0000\u00d6\u03d0\u0001\u0000\u0000\u0000\u00d8"+ - "\u03d5\u0001\u0000\u0000\u0000\u00da\u03d9\u0001\u0000\u0000\u0000\u00dc"+ - "\u03e1\u0001\u0000\u0000\u0000\u00de\u03f6\u0001\u0000\u0000\u0000\u00e0"+ - "\u03fa\u0001\u0000\u0000\u0000\u00e2\u03fe\u0001\u0000\u0000\u0000\u00e4"+ - "\u0402\u0001\u0000\u0000\u0000\u00e6\u0406\u0001\u0000\u0000\u0000\u00e8"+ - "\u040a\u0001\u0000\u0000\u0000\u00ea\u040f\u0001\u0000\u0000\u0000\u00ec"+ - "\u0413\u0001\u0000\u0000\u0000\u00ee\u0417\u0001\u0000\u0000\u0000\u00f0"+ - "\u041b\u0001\u0000\u0000\u0000\u00f2\u041e\u0001\u0000\u0000\u0000\u00f4"+ - "\u0422\u0001\u0000\u0000\u0000\u00f6\u0426\u0001\u0000\u0000\u0000\u00f8"+ - "\u042a\u0001\u0000\u0000\u0000\u00fa\u042e\u0001\u0000\u0000\u0000\u00fc"+ - "\u0433\u0001\u0000\u0000\u0000\u00fe\u0438\u0001\u0000\u0000\u0000\u0100"+ - "\u043d\u0001\u0000\u0000\u0000\u0102\u0444\u0001\u0000\u0000\u0000\u0104"+ - "\u044d\u0001\u0000\u0000\u0000\u0106\u0454\u0001\u0000\u0000\u0000\u0108"+ - "\u0458\u0001\u0000\u0000\u0000\u010a\u045c\u0001\u0000\u0000\u0000\u010c"+ - "\u0460\u0001\u0000\u0000\u0000\u010e\u0464\u0001\u0000\u0000\u0000\u0110"+ - "\u0468\u0001\u0000\u0000\u0000\u0112\u046e\u0001\u0000\u0000\u0000\u0114"+ - "\u0472\u0001\u0000\u0000\u0000\u0116\u0476\u0001\u0000\u0000\u0000\u0118"+ - "\u047a\u0001\u0000\u0000\u0000\u011a\u047e\u0001\u0000\u0000\u0000\u011c"+ - "\u0482\u0001\u0000\u0000\u0000\u011e\u0486\u0001\u0000\u0000\u0000\u0120"+ - "\u048a\u0001\u0000\u0000\u0000\u0122\u048e\u0001\u0000\u0000\u0000\u0124"+ - "\u0492\u0001\u0000\u0000\u0000\u0126\u0497\u0001\u0000\u0000\u0000\u0128"+ - "\u049b\u0001\u0000\u0000\u0000\u012a\u049f\u0001\u0000\u0000\u0000\u012c"+ - "\u04a4\u0001\u0000\u0000\u0000\u012e\u04a8\u0001\u0000\u0000\u0000\u0130"+ - "\u04ac\u0001\u0000\u0000\u0000\u0132\u04b0\u0001\u0000\u0000\u0000\u0134"+ - "\u04b4\u0001\u0000\u0000\u0000\u0136\u04ba\u0001\u0000\u0000\u0000\u0138"+ - "\u04be\u0001\u0000\u0000\u0000\u013a\u04c2\u0001\u0000\u0000\u0000\u013c"+ - "\u04c6\u0001\u0000\u0000\u0000\u013e\u04ca\u0001\u0000\u0000\u0000\u0140"+ - "\u04ce\u0001\u0000\u0000\u0000\u0142\u04d2\u0001\u0000\u0000\u0000\u0144"+ - "\u04d7\u0001\u0000\u0000\u0000\u0146\u04db\u0001\u0000\u0000\u0000\u0148"+ - "\u04df\u0001\u0000\u0000\u0000\u014a\u04e3\u0001\u0000\u0000\u0000\u014c"+ - "\u04e7\u0001\u0000\u0000\u0000\u014e\u04eb\u0001\u0000\u0000\u0000\u0150"+ - "\u04ef\u0001\u0000\u0000\u0000\u0152\u04f4\u0001\u0000\u0000\u0000\u0154"+ - "\u04f9\u0001\u0000\u0000\u0000\u0156\u04fd\u0001\u0000\u0000\u0000\u0158"+ - "\u0501\u0001\u0000\u0000\u0000\u015a\u0505\u0001\u0000\u0000\u0000\u015c"+ - "\u050a\u0001\u0000\u0000\u0000\u015e\u0514\u0001\u0000\u0000\u0000\u0160"+ - "\u0518\u0001\u0000\u0000\u0000\u0162\u051c\u0001\u0000\u0000\u0000\u0164"+ - "\u0520\u0001\u0000\u0000\u0000\u0166\u0525\u0001\u0000\u0000\u0000\u0168"+ - "\u052c\u0001\u0000\u0000\u0000\u016a\u0530\u0001\u0000\u0000\u0000\u016c"+ - "\u0534\u0001\u0000\u0000\u0000\u016e\u0538\u0001\u0000\u0000\u0000\u0170"+ - "\u053c\u0001\u0000\u0000\u0000\u0172\u0541\u0001\u0000\u0000\u0000\u0174"+ - "\u0547\u0001\u0000\u0000\u0000\u0176\u054b\u0001\u0000\u0000\u0000\u0178"+ - "\u054f\u0001\u0000\u0000\u0000\u017a\u0553\u0001\u0000\u0000\u0000\u017c"+ - "\u0559\u0001\u0000\u0000\u0000\u017e\u055d\u0001\u0000\u0000\u0000\u0180"+ - "\u0561\u0001\u0000\u0000\u0000\u0182\u0565\u0001\u0000\u0000\u0000\u0184"+ - "\u056b\u0001\u0000\u0000\u0000\u0186\u0571\u0001\u0000\u0000\u0000\u0188"+ - "\u0577\u0001\u0000\u0000\u0000\u018a\u018b\u0005d\u0000\u0000\u018b\u018c"+ - "\u0005i\u0000\u0000\u018c\u018d\u0005s\u0000\u0000\u018d\u018e\u0005s"+ - "\u0000\u0000\u018e\u018f\u0005e\u0000\u0000\u018f\u0190\u0005c\u0000\u0000"+ - "\u0190\u0191\u0005t\u0000\u0000\u0191\u0192\u0001\u0000\u0000\u0000\u0192"+ - "\u0193\u0006\u0000\u0000\u0000\u0193\u0011\u0001\u0000\u0000\u0000\u0194"+ - "\u0195\u0005d\u0000\u0000\u0195\u0196\u0005r\u0000\u0000\u0196\u0197\u0005"+ - "o\u0000\u0000\u0197\u0198\u0005p\u0000\u0000\u0198\u0199\u0001\u0000\u0000"+ - "\u0000\u0199\u019a\u0006\u0001\u0001\u0000\u019a\u0013\u0001\u0000\u0000"+ - "\u0000\u019b\u019c\u0005e\u0000\u0000\u019c\u019d\u0005n\u0000\u0000\u019d"+ - "\u019e\u0005r\u0000\u0000\u019e\u019f\u0005i\u0000\u0000\u019f\u01a0\u0005"+ - "c\u0000\u0000\u01a0\u01a1\u0005h\u0000\u0000\u01a1\u01a2\u0001\u0000\u0000"+ - "\u0000\u01a2\u01a3\u0006\u0002\u0002\u0000\u01a3\u0015\u0001\u0000\u0000"+ - "\u0000\u01a4\u01a5\u0005e\u0000\u0000\u01a5\u01a6\u0005v\u0000\u0000\u01a6"+ - "\u01a7\u0005a\u0000\u0000\u01a7\u01a8\u0005l\u0000\u0000\u01a8\u01a9\u0001"+ - "\u0000\u0000\u0000\u01a9\u01aa\u0006\u0003\u0000\u0000\u01aa\u0017\u0001"+ - "\u0000\u0000\u0000\u01ab\u01ac\u0005e\u0000\u0000\u01ac\u01ad\u0005x\u0000"+ - "\u0000\u01ad\u01ae\u0005p\u0000\u0000\u01ae\u01af\u0005l\u0000\u0000\u01af"+ - "\u01b0\u0005a\u0000\u0000\u01b0\u01b1\u0005i\u0000\u0000\u01b1\u01b2\u0005"+ - "n\u0000\u0000\u01b2\u01b3\u0001\u0000\u0000\u0000\u01b3\u01b4\u0006\u0004"+ - "\u0003\u0000\u01b4\u0019\u0001\u0000\u0000\u0000\u01b5\u01b6\u0005f\u0000"+ - "\u0000\u01b6\u01b7\u0005r\u0000\u0000\u01b7\u01b8\u0005o\u0000\u0000\u01b8"+ - "\u01b9\u0005m\u0000\u0000\u01b9\u01ba\u0001\u0000\u0000\u0000\u01ba\u01bb"+ - "\u0006\u0005\u0004\u0000\u01bb\u001b\u0001\u0000\u0000\u0000\u01bc\u01bd"+ - "\u0005g\u0000\u0000\u01bd\u01be\u0005r\u0000\u0000\u01be\u01bf\u0005o"+ - "\u0000\u0000\u01bf\u01c0\u0005k\u0000\u0000\u01c0\u01c1\u0001\u0000\u0000"+ - "\u0000\u01c1\u01c2\u0006\u0006\u0000\u0000\u01c2\u001d\u0001\u0000\u0000"+ - "\u0000\u01c3\u01c4\u0005i\u0000\u0000\u01c4\u01c5\u0005n\u0000\u0000\u01c5"+ - "\u01c6\u0005l\u0000\u0000\u01c6\u01c7\u0005i\u0000\u0000\u01c7\u01c8\u0005"+ - "n\u0000\u0000\u01c8\u01c9\u0005e\u0000\u0000\u01c9\u01ca\u0005s\u0000"+ - "\u0000\u01ca\u01cb\u0005t\u0000\u0000\u01cb\u01cc\u0005a\u0000\u0000\u01cc"+ - "\u01cd\u0005t\u0000\u0000\u01cd\u01ce\u0005s\u0000\u0000\u01ce\u01cf\u0001"+ - "\u0000\u0000\u0000\u01cf\u01d0\u0006\u0007\u0000\u0000\u01d0\u001f\u0001"+ - "\u0000\u0000\u0000\u01d1\u01d2\u0005k\u0000\u0000\u01d2\u01d3\u0005e\u0000"+ - "\u0000\u01d3\u01d4\u0005e\u0000\u0000\u01d4\u01d5\u0005p\u0000\u0000\u01d5"+ - "\u01d6\u0001\u0000\u0000\u0000\u01d6\u01d7\u0006\b\u0001\u0000\u01d7!"+ - "\u0001\u0000\u0000\u0000\u01d8\u01d9\u0005l\u0000\u0000\u01d9\u01da\u0005"+ - "i\u0000\u0000\u01da\u01db\u0005m\u0000\u0000\u01db\u01dc\u0005i\u0000"+ - "\u0000\u01dc\u01dd\u0005t\u0000\u0000\u01dd\u01de\u0001\u0000\u0000\u0000"+ - "\u01de\u01df\u0006\t\u0000\u0000\u01df#\u0001\u0000\u0000\u0000\u01e0"+ - "\u01e1\u0005l\u0000\u0000\u01e1\u01e2\u0005o\u0000\u0000\u01e2\u01e3\u0005"+ - "o\u0000\u0000\u01e3\u01e4\u0005k\u0000\u0000\u01e4\u01e5\u0005u\u0000"+ - "\u0000\u01e5\u01e6\u0005p\u0000\u0000\u01e6\u01e7\u0001\u0000\u0000\u0000"+ - "\u01e7\u01e8\u0006\n\u0005\u0000\u01e8%\u0001\u0000\u0000\u0000\u01e9"+ - "\u01ea\u0005m\u0000\u0000\u01ea\u01eb\u0005e\u0000\u0000\u01eb\u01ec\u0005"+ - "t\u0000\u0000\u01ec\u01ed\u0005a\u0000\u0000\u01ed\u01ee\u0001\u0000\u0000"+ - "\u0000\u01ee\u01ef\u0006\u000b\u0006\u0000\u01ef\'\u0001\u0000\u0000\u0000"+ - "\u01f0\u01f1\u0005m\u0000\u0000\u01f1\u01f2\u0005e\u0000\u0000\u01f2\u01f3"+ - "\u0005t\u0000\u0000\u01f3\u01f4\u0005r\u0000\u0000\u01f4\u01f5\u0005i"+ - "\u0000\u0000\u01f5\u01f6\u0005c\u0000\u0000\u01f6\u01f7\u0005s\u0000\u0000"+ - "\u01f7\u01f8\u0001\u0000\u0000\u0000\u01f8\u01f9\u0006\f\u0007\u0000\u01f9"+ - ")\u0001\u0000\u0000\u0000\u01fa\u01fb\u0005m\u0000\u0000\u01fb\u01fc\u0005"+ - "v\u0000\u0000\u01fc\u01fd\u0005_\u0000\u0000\u01fd\u01fe\u0005e\u0000"+ - "\u0000\u01fe\u01ff\u0005x\u0000\u0000\u01ff\u0200\u0005p\u0000\u0000\u0200"+ - "\u0201\u0005a\u0000\u0000\u0201\u0202\u0005n\u0000\u0000\u0202\u0203\u0005"+ - "d\u0000\u0000\u0203\u0204\u0001\u0000\u0000\u0000\u0204\u0205\u0006\r"+ - "\b\u0000\u0205+\u0001\u0000\u0000\u0000\u0206\u0207\u0005r\u0000\u0000"+ - "\u0207\u0208\u0005e\u0000\u0000\u0208\u0209\u0005n\u0000\u0000\u0209\u020a"+ - "\u0005a\u0000\u0000\u020a\u020b\u0005m\u0000\u0000\u020b\u020c\u0005e"+ - "\u0000\u0000\u020c\u020d\u0001\u0000\u0000\u0000\u020d\u020e\u0006\u000e"+ - "\t\u0000\u020e-\u0001\u0000\u0000\u0000\u020f\u0210\u0005r\u0000\u0000"+ - "\u0210\u0211\u0005o\u0000\u0000\u0211\u0212\u0005w\u0000\u0000\u0212\u0213"+ - "\u0001\u0000\u0000\u0000\u0213\u0214\u0006\u000f\u0000\u0000\u0214/\u0001"+ - "\u0000\u0000\u0000\u0215\u0216\u0005s\u0000\u0000\u0216\u0217\u0005h\u0000"+ - "\u0000\u0217\u0218\u0005o\u0000\u0000\u0218\u0219\u0005w\u0000\u0000\u0219"+ - "\u021a\u0001\u0000\u0000\u0000\u021a\u021b\u0006\u0010\n\u0000\u021b1"+ - "\u0001\u0000\u0000\u0000\u021c\u021d\u0005s\u0000\u0000\u021d\u021e\u0005"+ - "o\u0000\u0000\u021e\u021f\u0005r\u0000\u0000\u021f\u0220\u0005t\u0000"+ - "\u0000\u0220\u0221\u0001\u0000\u0000\u0000\u0221\u0222\u0006\u0011\u0000"+ - "\u0000\u02223\u0001\u0000\u0000\u0000\u0223\u0224\u0005s\u0000\u0000\u0224"+ - "\u0225\u0005t\u0000\u0000\u0225\u0226\u0005a\u0000\u0000\u0226\u0227\u0005"+ - "t\u0000\u0000\u0227\u0228\u0005s\u0000\u0000\u0228\u0229\u0001\u0000\u0000"+ - "\u0000\u0229\u022a\u0006\u0012\u0000\u0000\u022a5\u0001\u0000\u0000\u0000"+ - "\u022b\u022c\u0005w\u0000\u0000\u022c\u022d\u0005h\u0000\u0000\u022d\u022e"+ - "\u0005e\u0000\u0000\u022e\u022f\u0005r\u0000\u0000\u022f\u0230\u0005e"+ - "\u0000\u0000\u0230\u0231\u0001\u0000\u0000\u0000\u0231\u0232\u0006\u0013"+ - "\u0000\u0000\u02327\u0001\u0000\u0000\u0000\u0233\u0235\b\u0000\u0000"+ - "\u0000\u0234\u0233\u0001\u0000\u0000\u0000\u0235\u0236\u0001\u0000\u0000"+ - "\u0000\u0236\u0234\u0001\u0000\u0000\u0000\u0236\u0237\u0001\u0000\u0000"+ - "\u0000\u0237\u0238\u0001\u0000\u0000\u0000\u0238\u0239\u0006\u0014\u0000"+ - "\u0000\u02399\u0001\u0000\u0000\u0000\u023a\u023b\u0005/\u0000\u0000\u023b"+ - "\u023c\u0005/\u0000\u0000\u023c\u0240\u0001\u0000\u0000\u0000\u023d\u023f"+ - "\b\u0001\u0000\u0000\u023e\u023d\u0001\u0000\u0000\u0000\u023f\u0242\u0001"+ - "\u0000\u0000\u0000\u0240\u023e\u0001\u0000\u0000\u0000\u0240\u0241\u0001"+ - "\u0000\u0000\u0000\u0241\u0244\u0001\u0000\u0000\u0000\u0242\u0240\u0001"+ - "\u0000\u0000\u0000\u0243\u0245\u0005\r\u0000\u0000\u0244\u0243\u0001\u0000"+ - "\u0000\u0000\u0244\u0245\u0001\u0000\u0000\u0000\u0245\u0247\u0001\u0000"+ - "\u0000\u0000\u0246\u0248\u0005\n\u0000\u0000\u0247\u0246\u0001\u0000\u0000"+ - "\u0000\u0247\u0248\u0001\u0000\u0000\u0000\u0248\u0249\u0001\u0000\u0000"+ - "\u0000\u0249\u024a\u0006\u0015\u000b\u0000\u024a;\u0001\u0000\u0000\u0000"+ - "\u024b\u024c\u0005/\u0000\u0000\u024c\u024d\u0005*\u0000\u0000\u024d\u0252"+ - "\u0001\u0000\u0000\u0000\u024e\u0251\u0003<\u0016\u0000\u024f\u0251\t"+ - "\u0000\u0000\u0000\u0250\u024e\u0001\u0000\u0000\u0000\u0250\u024f\u0001"+ - "\u0000\u0000\u0000\u0251\u0254\u0001\u0000\u0000\u0000\u0252\u0253\u0001"+ - "\u0000\u0000\u0000\u0252\u0250\u0001\u0000\u0000\u0000\u0253\u0255\u0001"+ - "\u0000\u0000\u0000\u0254\u0252\u0001\u0000\u0000\u0000\u0255\u0256\u0005"+ - "*\u0000\u0000\u0256\u0257\u0005/\u0000\u0000\u0257\u0258\u0001\u0000\u0000"+ - "\u0000\u0258\u0259\u0006\u0016\u000b\u0000\u0259=\u0001\u0000\u0000\u0000"+ - "\u025a\u025c\u0007\u0002\u0000\u0000\u025b\u025a\u0001\u0000\u0000\u0000"+ - "\u025c\u025d\u0001\u0000\u0000\u0000\u025d\u025b\u0001\u0000\u0000\u0000"+ - "\u025d\u025e\u0001\u0000\u0000\u0000\u025e\u025f\u0001\u0000\u0000\u0000"+ - "\u025f\u0260\u0006\u0017\u000b\u0000\u0260?\u0001\u0000\u0000\u0000\u0261"+ - "\u0265\b\u0003\u0000\u0000\u0262\u0263\u0005/\u0000\u0000\u0263\u0265"+ - "\b\u0004\u0000\u0000\u0264\u0261\u0001\u0000\u0000\u0000\u0264\u0262\u0001"+ - "\u0000\u0000\u0000\u0265A\u0001\u0000\u0000\u0000\u0266\u0268\u0003@\u0018"+ - "\u0000\u0267\u0266\u0001\u0000\u0000\u0000\u0268\u0269\u0001\u0000\u0000"+ - "\u0000\u0269\u0267\u0001\u0000\u0000\u0000\u0269\u026a\u0001\u0000\u0000"+ - "\u0000\u026aC\u0001\u0000\u0000\u0000\u026b\u026c\u0003\u00b0P\u0000\u026c"+ - "\u026d\u0001\u0000\u0000\u0000\u026d\u026e\u0006\u001a\f\u0000\u026e\u026f"+ - "\u0006\u001a\r\u0000\u026fE\u0001\u0000\u0000\u0000\u0270\u0271\u0003"+ - "N\u001f\u0000\u0271\u0272\u0001\u0000\u0000\u0000\u0272\u0273\u0006\u001b"+ - "\u000e\u0000\u0273\u0274\u0006\u001b\u000f\u0000\u0274G\u0001\u0000\u0000"+ - "\u0000\u0275\u0276\u0003>\u0017\u0000\u0276\u0277\u0001\u0000\u0000\u0000"+ - "\u0277\u0278\u0006\u001c\u000b\u0000\u0278I\u0001\u0000\u0000\u0000\u0279"+ - "\u027a\u0003:\u0015\u0000\u027a\u027b\u0001\u0000\u0000\u0000\u027b\u027c"+ - "\u0006\u001d\u000b\u0000\u027cK\u0001\u0000\u0000\u0000\u027d\u027e\u0003"+ - "<\u0016\u0000\u027e\u027f\u0001\u0000\u0000\u0000\u027f\u0280\u0006\u001e"+ - "\u000b\u0000\u0280M\u0001\u0000\u0000\u0000\u0281\u0282\u0005|\u0000\u0000"+ - "\u0282\u0283\u0001\u0000\u0000\u0000\u0283\u0284\u0006\u001f\u000f\u0000"+ - "\u0284O\u0001\u0000\u0000\u0000\u0285\u0286\u0007\u0005\u0000\u0000\u0286"+ - "Q\u0001\u0000\u0000\u0000\u0287\u0288\u0007\u0006\u0000\u0000\u0288S\u0001"+ - "\u0000\u0000\u0000\u0289\u028a\u0005\\\u0000\u0000\u028a\u028b\u0007\u0007"+ - "\u0000\u0000\u028bU\u0001\u0000\u0000\u0000\u028c\u028d\b\b\u0000\u0000"+ - "\u028dW\u0001\u0000\u0000\u0000\u028e\u0290\u0007\t\u0000\u0000\u028f"+ - "\u0291\u0007\n\u0000\u0000\u0290\u028f\u0001\u0000\u0000\u0000\u0290\u0291"+ - "\u0001\u0000\u0000\u0000\u0291\u0293\u0001\u0000\u0000\u0000\u0292\u0294"+ - "\u0003P \u0000\u0293\u0292\u0001\u0000\u0000\u0000\u0294\u0295\u0001\u0000"+ - "\u0000\u0000\u0295\u0293\u0001\u0000\u0000\u0000\u0295\u0296\u0001\u0000"+ - "\u0000\u0000\u0296Y\u0001\u0000\u0000\u0000\u0297\u0298\u0005@\u0000\u0000"+ - "\u0298[\u0001\u0000\u0000\u0000\u0299\u029a\u0005`\u0000\u0000\u029a]"+ - "\u0001\u0000\u0000\u0000\u029b\u029f\b\u000b\u0000\u0000\u029c\u029d\u0005"+ - "`\u0000\u0000\u029d\u029f\u0005`\u0000\u0000\u029e\u029b\u0001\u0000\u0000"+ - "\u0000\u029e\u029c\u0001\u0000\u0000\u0000\u029f_\u0001\u0000\u0000\u0000"+ - "\u02a0\u02a1\u0005_\u0000\u0000\u02a1a\u0001\u0000\u0000\u0000\u02a2\u02a6"+ - "\u0003R!\u0000\u02a3\u02a6\u0003P \u0000\u02a4\u02a6\u0003`(\u0000\u02a5"+ - "\u02a2\u0001\u0000\u0000\u0000\u02a5\u02a3\u0001\u0000\u0000\u0000\u02a5"+ - "\u02a4\u0001\u0000\u0000\u0000\u02a6c\u0001\u0000\u0000\u0000\u02a7\u02ac"+ - "\u0005\"\u0000\u0000\u02a8\u02ab\u0003T\"\u0000\u02a9\u02ab\u0003V#\u0000"+ - "\u02aa\u02a8\u0001\u0000\u0000\u0000\u02aa\u02a9\u0001\u0000\u0000\u0000"+ - "\u02ab\u02ae\u0001\u0000\u0000\u0000\u02ac\u02aa\u0001\u0000\u0000\u0000"+ - "\u02ac\u02ad\u0001\u0000\u0000\u0000\u02ad\u02af\u0001\u0000\u0000\u0000"+ - "\u02ae\u02ac\u0001\u0000\u0000\u0000\u02af\u02c5\u0005\"\u0000\u0000\u02b0"+ - "\u02b1\u0005\"\u0000\u0000\u02b1\u02b2\u0005\"\u0000\u0000\u02b2\u02b3"+ - "\u0005\"\u0000\u0000\u02b3\u02b7\u0001\u0000\u0000\u0000\u02b4\u02b6\b"+ - "\u0001\u0000\u0000\u02b5\u02b4\u0001\u0000\u0000\u0000\u02b6\u02b9\u0001"+ - "\u0000\u0000\u0000\u02b7\u02b8\u0001\u0000\u0000\u0000\u02b7\u02b5\u0001"+ - "\u0000\u0000\u0000\u02b8\u02ba\u0001\u0000\u0000\u0000\u02b9\u02b7\u0001"+ - "\u0000\u0000\u0000\u02ba\u02bb\u0005\"\u0000\u0000\u02bb\u02bc\u0005\""+ - "\u0000\u0000\u02bc\u02bd\u0005\"\u0000\u0000\u02bd\u02bf\u0001\u0000\u0000"+ - "\u0000\u02be\u02c0\u0005\"\u0000\u0000\u02bf\u02be\u0001\u0000\u0000\u0000"+ - "\u02bf\u02c0\u0001\u0000\u0000\u0000\u02c0\u02c2\u0001\u0000\u0000\u0000"+ - "\u02c1\u02c3\u0005\"\u0000\u0000\u02c2\u02c1\u0001\u0000\u0000\u0000\u02c2"+ - "\u02c3\u0001\u0000\u0000\u0000\u02c3\u02c5\u0001\u0000\u0000\u0000\u02c4"+ - "\u02a7\u0001\u0000\u0000\u0000\u02c4\u02b0\u0001\u0000\u0000\u0000\u02c5"+ - "e\u0001\u0000\u0000\u0000\u02c6\u02c8\u0003P \u0000\u02c7\u02c6\u0001"+ - "\u0000\u0000\u0000\u02c8\u02c9\u0001\u0000\u0000\u0000\u02c9\u02c7\u0001"+ - "\u0000\u0000\u0000\u02c9\u02ca\u0001\u0000\u0000\u0000\u02cag\u0001\u0000"+ - "\u0000\u0000\u02cb\u02cd\u0003P \u0000\u02cc\u02cb\u0001\u0000\u0000\u0000"+ - "\u02cd\u02ce\u0001\u0000\u0000\u0000\u02ce\u02cc\u0001\u0000\u0000\u0000"+ - "\u02ce\u02cf\u0001\u0000\u0000\u0000\u02cf\u02d0\u0001\u0000\u0000\u0000"+ - "\u02d0\u02d4\u0003x4\u0000\u02d1\u02d3\u0003P \u0000\u02d2\u02d1\u0001"+ - "\u0000\u0000\u0000\u02d3\u02d6\u0001\u0000\u0000\u0000\u02d4\u02d2\u0001"+ - "\u0000\u0000\u0000\u02d4\u02d5\u0001\u0000\u0000\u0000\u02d5\u02f6\u0001"+ - "\u0000\u0000\u0000\u02d6\u02d4\u0001\u0000\u0000\u0000\u02d7\u02d9\u0003"+ - "x4\u0000\u02d8\u02da\u0003P \u0000\u02d9\u02d8\u0001\u0000\u0000\u0000"+ - "\u02da\u02db\u0001\u0000\u0000\u0000\u02db\u02d9\u0001\u0000\u0000\u0000"+ - "\u02db\u02dc\u0001\u0000\u0000\u0000\u02dc\u02f6\u0001\u0000\u0000\u0000"+ - "\u02dd\u02df\u0003P \u0000\u02de\u02dd\u0001\u0000\u0000\u0000\u02df\u02e0"+ - "\u0001\u0000\u0000\u0000\u02e0\u02de\u0001\u0000\u0000\u0000\u02e0\u02e1"+ - "\u0001\u0000\u0000\u0000\u02e1\u02e9\u0001\u0000\u0000\u0000\u02e2\u02e6"+ - "\u0003x4\u0000\u02e3\u02e5\u0003P \u0000\u02e4\u02e3\u0001\u0000\u0000"+ - "\u0000\u02e5\u02e8\u0001\u0000\u0000\u0000\u02e6\u02e4\u0001\u0000\u0000"+ - "\u0000\u02e6\u02e7\u0001\u0000\u0000\u0000\u02e7\u02ea\u0001\u0000\u0000"+ - "\u0000\u02e8\u02e6\u0001\u0000\u0000\u0000\u02e9\u02e2\u0001\u0000\u0000"+ - "\u0000\u02e9\u02ea\u0001\u0000\u0000\u0000\u02ea\u02eb\u0001\u0000\u0000"+ - "\u0000\u02eb\u02ec\u0003X$\u0000\u02ec\u02f6\u0001\u0000\u0000\u0000\u02ed"+ - "\u02ef\u0003x4\u0000\u02ee\u02f0\u0003P \u0000\u02ef\u02ee\u0001\u0000"+ - "\u0000\u0000\u02f0\u02f1\u0001\u0000\u0000\u0000\u02f1\u02ef\u0001\u0000"+ - "\u0000\u0000\u02f1\u02f2\u0001\u0000\u0000\u0000\u02f2\u02f3\u0001\u0000"+ - "\u0000\u0000\u02f3\u02f4\u0003X$\u0000\u02f4\u02f6\u0001\u0000\u0000\u0000"+ - "\u02f5\u02cc\u0001\u0000\u0000\u0000\u02f5\u02d7\u0001\u0000\u0000\u0000"+ - "\u02f5\u02de\u0001\u0000\u0000\u0000\u02f5\u02ed\u0001\u0000\u0000\u0000"+ - "\u02f6i\u0001\u0000\u0000\u0000\u02f7\u02f8\u0005b\u0000\u0000\u02f8\u02f9"+ - "\u0005y\u0000\u0000\u02f9k\u0001\u0000\u0000\u0000\u02fa\u02fb\u0005a"+ - "\u0000\u0000\u02fb\u02fc\u0005n\u0000\u0000\u02fc\u02fd\u0005d\u0000\u0000"+ - "\u02fdm\u0001\u0000\u0000\u0000\u02fe\u02ff\u0005a\u0000\u0000\u02ff\u0300"+ - "\u0005s\u0000\u0000\u0300\u0301\u0005c\u0000\u0000\u0301o\u0001\u0000"+ - "\u0000\u0000\u0302\u0303\u0005=\u0000\u0000\u0303q\u0001\u0000\u0000\u0000"+ - "\u0304\u0305\u0005:\u0000\u0000\u0305\u0306\u0005:\u0000\u0000\u0306s"+ - "\u0001\u0000\u0000\u0000\u0307\u0308\u0005,\u0000\u0000\u0308u\u0001\u0000"+ - "\u0000\u0000\u0309\u030a\u0005d\u0000\u0000\u030a\u030b\u0005e\u0000\u0000"+ - "\u030b\u030c\u0005s\u0000\u0000\u030c\u030d\u0005c\u0000\u0000\u030dw"+ - "\u0001\u0000\u0000\u0000\u030e\u030f\u0005.\u0000\u0000\u030fy\u0001\u0000"+ - "\u0000\u0000\u0310\u0311\u0005f\u0000\u0000\u0311\u0312\u0005a\u0000\u0000"+ - "\u0312\u0313\u0005l\u0000\u0000\u0313\u0314\u0005s\u0000\u0000\u0314\u0315"+ - "\u0005e\u0000\u0000\u0315{\u0001\u0000\u0000\u0000\u0316\u0317\u0005f"+ - "\u0000\u0000\u0317\u0318\u0005i\u0000\u0000\u0318\u0319\u0005r\u0000\u0000"+ - "\u0319\u031a\u0005s\u0000\u0000\u031a\u031b\u0005t\u0000\u0000\u031b}"+ - "\u0001\u0000\u0000\u0000\u031c\u031d\u0005l\u0000\u0000\u031d\u031e\u0005"+ - "a\u0000\u0000\u031e\u031f\u0005s\u0000\u0000\u031f\u0320\u0005t\u0000"+ - "\u0000\u0320\u007f\u0001\u0000\u0000\u0000\u0321\u0322\u0005(\u0000\u0000"+ - "\u0322\u0081\u0001\u0000\u0000\u0000\u0323\u0324\u0005i\u0000\u0000\u0324"+ - "\u0325\u0005n\u0000\u0000\u0325\u0083\u0001\u0000\u0000\u0000\u0326\u0327"+ - "\u0005i\u0000\u0000\u0327\u0328\u0005s\u0000\u0000\u0328\u0085\u0001\u0000"+ - "\u0000\u0000\u0329\u032a\u0005l\u0000\u0000\u032a\u032b\u0005i\u0000\u0000"+ - "\u032b\u032c\u0005k\u0000\u0000\u032c\u032d\u0005e\u0000\u0000\u032d\u0087"+ - "\u0001\u0000\u0000\u0000\u032e\u032f\u0005n\u0000\u0000\u032f\u0330\u0005"+ - "o\u0000\u0000\u0330\u0331\u0005t\u0000\u0000\u0331\u0089\u0001\u0000\u0000"+ - "\u0000\u0332\u0333\u0005n\u0000\u0000\u0333\u0334\u0005u\u0000\u0000\u0334"+ - "\u0335\u0005l\u0000\u0000\u0335\u0336\u0005l\u0000\u0000\u0336\u008b\u0001"+ - "\u0000\u0000\u0000\u0337\u0338\u0005n\u0000\u0000\u0338\u0339\u0005u\u0000"+ - "\u0000\u0339\u033a\u0005l\u0000\u0000\u033a\u033b\u0005l\u0000\u0000\u033b"+ - "\u033c\u0005s\u0000\u0000\u033c\u008d\u0001\u0000\u0000\u0000\u033d\u033e"+ - "\u0005o\u0000\u0000\u033e\u033f\u0005r\u0000\u0000\u033f\u008f\u0001\u0000"+ - "\u0000\u0000\u0340\u0341\u0005?\u0000\u0000\u0341\u0091\u0001\u0000\u0000"+ - "\u0000\u0342\u0343\u0005r\u0000\u0000\u0343\u0344\u0005l\u0000\u0000\u0344"+ - "\u0345\u0005i\u0000\u0000\u0345\u0346\u0005k\u0000\u0000\u0346\u0347\u0005"+ - "e\u0000\u0000\u0347\u0093\u0001\u0000\u0000\u0000\u0348\u0349\u0005)\u0000"+ - "\u0000\u0349\u0095\u0001\u0000\u0000\u0000\u034a\u034b\u0005t\u0000\u0000"+ - "\u034b\u034c\u0005r\u0000\u0000\u034c\u034d\u0005u\u0000\u0000\u034d\u034e"+ - "\u0005e\u0000\u0000\u034e\u0097\u0001\u0000\u0000\u0000\u034f\u0350\u0005"+ - "=\u0000\u0000\u0350\u0351\u0005=\u0000\u0000\u0351\u0099\u0001\u0000\u0000"+ - "\u0000\u0352\u0353\u0005=\u0000\u0000\u0353\u0354\u0005~\u0000\u0000\u0354"+ - "\u009b\u0001\u0000\u0000\u0000\u0355\u0356\u0005!\u0000\u0000\u0356\u0357"+ - "\u0005=\u0000\u0000\u0357\u009d\u0001\u0000\u0000\u0000\u0358\u0359\u0005"+ - "<\u0000\u0000\u0359\u009f\u0001\u0000\u0000\u0000\u035a\u035b\u0005<\u0000"+ - "\u0000\u035b\u035c\u0005=\u0000\u0000\u035c\u00a1\u0001\u0000\u0000\u0000"+ - "\u035d\u035e\u0005>\u0000\u0000\u035e\u00a3\u0001\u0000\u0000\u0000\u035f"+ - "\u0360\u0005>\u0000\u0000\u0360\u0361\u0005=\u0000\u0000\u0361\u00a5\u0001"+ - "\u0000\u0000\u0000\u0362\u0363\u0005+\u0000\u0000\u0363\u00a7\u0001\u0000"+ - "\u0000\u0000\u0364\u0365\u0005-\u0000\u0000\u0365\u00a9\u0001\u0000\u0000"+ - "\u0000\u0366\u0367\u0005*\u0000\u0000\u0367\u00ab\u0001\u0000\u0000\u0000"+ - "\u0368\u0369\u0005/\u0000\u0000\u0369\u00ad\u0001\u0000\u0000\u0000\u036a"+ - "\u036b\u0005%\u0000\u0000\u036b\u00af\u0001\u0000\u0000\u0000\u036c\u036d"+ - "\u0005[\u0000\u0000\u036d\u036e\u0001\u0000\u0000\u0000\u036e\u036f\u0006"+ - "P\u0000\u0000\u036f\u0370\u0006P\u0000\u0000\u0370\u00b1\u0001\u0000\u0000"+ - "\u0000\u0371\u0372\u0005]\u0000\u0000\u0372\u0373\u0001\u0000\u0000\u0000"+ - "\u0373\u0374\u0006Q\u000f\u0000\u0374\u0375\u0006Q\u000f\u0000\u0375\u00b3"+ - "\u0001\u0000\u0000\u0000\u0376\u037a\u0003R!\u0000\u0377\u0379\u0003b"+ - ")\u0000\u0378\u0377\u0001\u0000\u0000\u0000\u0379\u037c\u0001\u0000\u0000"+ - "\u0000\u037a\u0378\u0001\u0000\u0000\u0000\u037a\u037b\u0001\u0000\u0000"+ - "\u0000\u037b\u0387\u0001\u0000\u0000\u0000\u037c\u037a\u0001\u0000\u0000"+ - "\u0000\u037d\u0380\u0003`(\u0000\u037e\u0380\u0003Z%\u0000\u037f\u037d"+ - "\u0001\u0000\u0000\u0000\u037f\u037e\u0001\u0000\u0000\u0000\u0380\u0382"+ - "\u0001\u0000\u0000\u0000\u0381\u0383\u0003b)\u0000\u0382\u0381\u0001\u0000"+ - "\u0000\u0000\u0383\u0384\u0001\u0000\u0000\u0000\u0384\u0382\u0001\u0000"+ - "\u0000\u0000\u0384\u0385\u0001\u0000\u0000\u0000\u0385\u0387\u0001\u0000"+ - "\u0000\u0000\u0386\u0376\u0001\u0000\u0000\u0000\u0386\u037f\u0001\u0000"+ - "\u0000\u0000\u0387\u00b5\u0001\u0000\u0000\u0000\u0388\u038a\u0003\\&"+ - "\u0000\u0389\u038b\u0003^\'\u0000\u038a\u0389\u0001\u0000\u0000\u0000"+ - "\u038b\u038c\u0001\u0000\u0000\u0000\u038c\u038a\u0001\u0000\u0000\u0000"+ - "\u038c\u038d\u0001\u0000\u0000\u0000\u038d\u038e\u0001\u0000\u0000\u0000"+ - "\u038e\u038f\u0003\\&\u0000\u038f\u00b7\u0001\u0000\u0000\u0000\u0390"+ - "\u0391\u0003\u00b6S\u0000\u0391\u00b9\u0001\u0000\u0000\u0000\u0392\u0393"+ - "\u0003:\u0015\u0000\u0393\u0394\u0001\u0000\u0000\u0000\u0394\u0395\u0006"+ - "U\u000b\u0000\u0395\u00bb\u0001\u0000\u0000\u0000\u0396\u0397\u0003<\u0016"+ - "\u0000\u0397\u0398\u0001\u0000\u0000\u0000\u0398\u0399\u0006V\u000b\u0000"+ - "\u0399\u00bd\u0001\u0000\u0000\u0000\u039a\u039b\u0003>\u0017\u0000\u039b"+ - "\u039c\u0001\u0000\u0000\u0000\u039c\u039d\u0006W\u000b\u0000\u039d\u00bf"+ - "\u0001\u0000\u0000\u0000\u039e\u039f\u0003N\u001f\u0000\u039f\u03a0\u0001"+ - "\u0000\u0000\u0000\u03a0\u03a1\u0006X\u000e\u0000\u03a1\u03a2\u0006X\u000f"+ - "\u0000\u03a2\u00c1\u0001\u0000\u0000\u0000\u03a3\u03a4\u0003\u00b0P\u0000"+ - "\u03a4\u03a5\u0001\u0000\u0000\u0000\u03a5\u03a6\u0006Y\f\u0000\u03a6"+ - "\u00c3\u0001\u0000\u0000\u0000\u03a7\u03a8\u0003\u00b2Q\u0000\u03a8\u03a9"+ - "\u0001\u0000\u0000\u0000\u03a9\u03aa\u0006Z\u0010\u0000\u03aa\u00c5\u0001"+ - "\u0000\u0000\u0000\u03ab\u03ac\u0003t2\u0000\u03ac\u03ad\u0001\u0000\u0000"+ - "\u0000\u03ad\u03ae\u0006[\u0011\u0000\u03ae\u00c7\u0001\u0000\u0000\u0000"+ - "\u03af\u03b0\u0003p0\u0000\u03b0\u03b1\u0001\u0000\u0000\u0000\u03b1\u03b2"+ - "\u0006\\\u0012\u0000\u03b2\u00c9\u0001\u0000\u0000\u0000\u03b3\u03b4\u0003"+ - "d*\u0000\u03b4\u03b5\u0001\u0000\u0000\u0000\u03b5\u03b6\u0006]\u0013"+ - "\u0000\u03b6\u00cb\u0001\u0000\u0000\u0000\u03b7\u03b8\u0005m\u0000\u0000"+ - "\u03b8\u03b9\u0005e\u0000\u0000\u03b9\u03ba\u0005t\u0000\u0000\u03ba\u03bb"+ - "\u0005a\u0000\u0000\u03bb\u03bc\u0005d\u0000\u0000\u03bc\u03bd\u0005a"+ - "\u0000\u0000\u03bd\u03be\u0005t\u0000\u0000\u03be\u03bf\u0005a\u0000\u0000"+ - "\u03bf\u00cd\u0001\u0000\u0000\u0000\u03c0\u03c1\u0003B\u0019\u0000\u03c1"+ - "\u03c2\u0001\u0000\u0000\u0000\u03c2\u03c3\u0006_\u0014\u0000\u03c3\u00cf"+ - "\u0001\u0000\u0000\u0000\u03c4\u03c5\u0003:\u0015\u0000\u03c5\u03c6\u0001"+ - "\u0000\u0000\u0000\u03c6\u03c7\u0006`\u000b\u0000\u03c7\u00d1\u0001\u0000"+ - "\u0000\u0000\u03c8\u03c9\u0003<\u0016\u0000\u03c9\u03ca\u0001\u0000\u0000"+ - "\u0000\u03ca\u03cb\u0006a\u000b\u0000\u03cb\u00d3\u0001\u0000\u0000\u0000"+ - "\u03cc\u03cd\u0003>\u0017\u0000\u03cd\u03ce\u0001\u0000\u0000\u0000\u03ce"+ - "\u03cf\u0006b\u000b\u0000\u03cf\u00d5\u0001\u0000\u0000\u0000\u03d0\u03d1"+ - "\u0003N\u001f\u0000\u03d1\u03d2\u0001\u0000\u0000\u0000\u03d2\u03d3\u0006"+ - "c\u000e\u0000\u03d3\u03d4\u0006c\u000f\u0000\u03d4\u00d7\u0001\u0000\u0000"+ - "\u0000\u03d5\u03d6\u0003x4\u0000\u03d6\u03d7\u0001\u0000\u0000\u0000\u03d7"+ - "\u03d8\u0006d\u0015\u0000\u03d8\u00d9\u0001\u0000\u0000\u0000\u03d9\u03da"+ - "\u0003t2\u0000\u03da\u03db\u0001\u0000\u0000\u0000\u03db\u03dc\u0006e"+ - "\u0011\u0000\u03dc\u00db\u0001\u0000\u0000\u0000\u03dd\u03e2\u0003R!\u0000"+ - "\u03de\u03e2\u0003P \u0000\u03df\u03e2\u0003`(\u0000\u03e0\u03e2\u0003"+ - "\u00aaM\u0000\u03e1\u03dd\u0001\u0000\u0000\u0000\u03e1\u03de\u0001\u0000"+ - "\u0000\u0000\u03e1\u03df\u0001\u0000\u0000\u0000\u03e1\u03e0\u0001\u0000"+ - "\u0000\u0000\u03e2\u00dd\u0001\u0000\u0000\u0000\u03e3\u03e6\u0003R!\u0000"+ - "\u03e4\u03e6\u0003\u00aaM\u0000\u03e5\u03e3\u0001\u0000\u0000\u0000\u03e5"+ - "\u03e4\u0001\u0000\u0000\u0000\u03e6\u03ea\u0001\u0000\u0000\u0000\u03e7"+ - "\u03e9\u0003\u00dcf\u0000\u03e8\u03e7\u0001\u0000\u0000\u0000\u03e9\u03ec"+ - "\u0001\u0000\u0000\u0000\u03ea\u03e8\u0001\u0000\u0000\u0000\u03ea\u03eb"+ - "\u0001\u0000\u0000\u0000\u03eb\u03f7\u0001\u0000\u0000\u0000\u03ec\u03ea"+ - "\u0001\u0000\u0000\u0000\u03ed\u03f0\u0003`(\u0000\u03ee\u03f0\u0003Z"+ - "%\u0000\u03ef\u03ed\u0001\u0000\u0000\u0000\u03ef\u03ee\u0001\u0000\u0000"+ - "\u0000\u03f0\u03f2\u0001\u0000\u0000\u0000\u03f1\u03f3\u0003\u00dcf\u0000"+ - "\u03f2\u03f1\u0001\u0000\u0000\u0000\u03f3\u03f4\u0001\u0000\u0000\u0000"+ - "\u03f4\u03f2\u0001\u0000\u0000\u0000\u03f4\u03f5\u0001\u0000\u0000\u0000"+ - "\u03f5\u03f7\u0001\u0000\u0000\u0000\u03f6\u03e5\u0001\u0000\u0000\u0000"+ - "\u03f6\u03ef\u0001\u0000\u0000\u0000\u03f7\u00df\u0001\u0000\u0000\u0000"+ - "\u03f8\u03fb\u0003\u00deg\u0000\u03f9\u03fb\u0003\u00b6S\u0000\u03fa\u03f8"+ - "\u0001\u0000\u0000\u0000\u03fa\u03f9\u0001\u0000\u0000\u0000\u03fb\u03fc"+ - "\u0001\u0000\u0000\u0000\u03fc\u03fa\u0001\u0000\u0000\u0000\u03fc\u03fd"+ - "\u0001\u0000\u0000\u0000\u03fd\u00e1\u0001\u0000\u0000\u0000\u03fe\u03ff"+ - "\u0003:\u0015\u0000\u03ff\u0400\u0001\u0000\u0000\u0000\u0400\u0401\u0006"+ - "i\u000b\u0000\u0401\u00e3\u0001\u0000\u0000\u0000\u0402\u0403\u0003<\u0016"+ - "\u0000\u0403\u0404\u0001\u0000\u0000\u0000\u0404\u0405\u0006j\u000b\u0000"+ - "\u0405\u00e5\u0001\u0000\u0000\u0000\u0406\u0407\u0003>\u0017\u0000\u0407"+ - "\u0408\u0001\u0000\u0000\u0000\u0408\u0409\u0006k\u000b\u0000\u0409\u00e7"+ - "\u0001\u0000\u0000\u0000\u040a\u040b\u0003N\u001f\u0000\u040b\u040c\u0001"+ - "\u0000\u0000\u0000\u040c\u040d\u0006l\u000e\u0000\u040d\u040e\u0006l\u000f"+ - "\u0000\u040e\u00e9\u0001\u0000\u0000\u0000\u040f\u0410\u0003p0\u0000\u0410"+ - "\u0411\u0001\u0000\u0000\u0000\u0411\u0412\u0006m\u0012\u0000\u0412\u00eb"+ - "\u0001\u0000\u0000\u0000\u0413\u0414\u0003t2\u0000\u0414\u0415\u0001\u0000"+ - "\u0000\u0000\u0415\u0416\u0006n\u0011\u0000\u0416\u00ed\u0001\u0000\u0000"+ - "\u0000\u0417\u0418\u0003x4\u0000\u0418\u0419\u0001\u0000\u0000\u0000\u0419"+ - "\u041a\u0006o\u0015\u0000\u041a\u00ef\u0001\u0000\u0000\u0000\u041b\u041c"+ - "\u0005a\u0000\u0000\u041c\u041d\u0005s\u0000\u0000\u041d\u00f1\u0001\u0000"+ - "\u0000\u0000\u041e\u041f\u0003\u00e0h\u0000\u041f\u0420\u0001\u0000\u0000"+ - "\u0000\u0420\u0421\u0006q\u0016\u0000\u0421\u00f3\u0001\u0000\u0000\u0000"+ - "\u0422\u0423\u0003:\u0015\u0000\u0423\u0424\u0001\u0000\u0000\u0000\u0424"+ - "\u0425\u0006r\u000b\u0000\u0425\u00f5\u0001\u0000\u0000\u0000\u0426\u0427"+ - "\u0003<\u0016\u0000\u0427\u0428\u0001\u0000\u0000\u0000\u0428\u0429\u0006"+ - "s\u000b\u0000\u0429\u00f7\u0001\u0000\u0000\u0000\u042a\u042b\u0003>\u0017"+ - "\u0000\u042b\u042c\u0001\u0000\u0000\u0000\u042c\u042d\u0006t\u000b\u0000"+ - "\u042d\u00f9\u0001\u0000\u0000\u0000\u042e\u042f\u0003N\u001f\u0000\u042f"+ - "\u0430\u0001\u0000\u0000\u0000\u0430\u0431\u0006u\u000e\u0000\u0431\u0432"+ - "\u0006u\u000f\u0000\u0432\u00fb\u0001\u0000\u0000\u0000\u0433\u0434\u0003"+ - "\u00b0P\u0000\u0434\u0435\u0001\u0000\u0000\u0000\u0435\u0436\u0006v\f"+ - "\u0000\u0436\u0437\u0006v\u0017\u0000\u0437\u00fd\u0001\u0000\u0000\u0000"+ - "\u0438\u0439\u0005o\u0000\u0000\u0439\u043a\u0005n\u0000\u0000\u043a\u043b"+ - "\u0001\u0000\u0000\u0000\u043b\u043c\u0006w\u0018\u0000\u043c\u00ff\u0001"+ - "\u0000\u0000\u0000\u043d\u043e\u0005w\u0000\u0000\u043e\u043f\u0005i\u0000"+ - "\u0000\u043f\u0440\u0005t\u0000\u0000\u0440\u0441\u0005h\u0000\u0000\u0441"+ - "\u0442\u0001\u0000\u0000\u0000\u0442\u0443\u0006x\u0018\u0000\u0443\u0101"+ - "\u0001\u0000\u0000\u0000\u0444\u0445\b\f\u0000\u0000\u0445\u0103\u0001"+ - "\u0000\u0000\u0000\u0446\u0448\u0003\u0102y\u0000\u0447\u0446\u0001\u0000"+ - "\u0000\u0000\u0448\u0449\u0001\u0000\u0000\u0000\u0449\u0447\u0001\u0000"+ - "\u0000\u0000\u0449\u044a\u0001\u0000\u0000\u0000\u044a\u044b\u0001\u0000"+ - "\u0000\u0000\u044b\u044c\u0003\u0166\u00ab\u0000\u044c\u044e\u0001\u0000"+ - "\u0000\u0000\u044d\u0447\u0001\u0000\u0000\u0000\u044d\u044e\u0001\u0000"+ - "\u0000\u0000\u044e\u0450\u0001\u0000\u0000\u0000\u044f\u0451\u0003\u0102"+ - "y\u0000\u0450\u044f\u0001\u0000\u0000\u0000\u0451\u0452\u0001\u0000\u0000"+ - "\u0000\u0452\u0450\u0001\u0000\u0000\u0000\u0452\u0453\u0001\u0000\u0000"+ - "\u0000\u0453\u0105\u0001\u0000\u0000\u0000\u0454\u0455\u0003\u00b8T\u0000"+ - "\u0455\u0456\u0001\u0000\u0000\u0000\u0456\u0457\u0006{\u0019\u0000\u0457"+ - "\u0107\u0001\u0000\u0000\u0000\u0458\u0459\u0003\u0104z\u0000\u0459\u045a"+ - "\u0001\u0000\u0000\u0000\u045a\u045b\u0006|\u001a\u0000\u045b\u0109\u0001"+ - "\u0000\u0000\u0000\u045c\u045d\u0003:\u0015\u0000\u045d\u045e\u0001\u0000"+ - "\u0000\u0000\u045e\u045f\u0006}\u000b\u0000\u045f\u010b\u0001\u0000\u0000"+ - "\u0000\u0460\u0461\u0003<\u0016\u0000\u0461\u0462\u0001\u0000\u0000\u0000"+ - "\u0462\u0463\u0006~\u000b\u0000\u0463\u010d\u0001\u0000\u0000\u0000\u0464"+ - "\u0465\u0003>\u0017\u0000\u0465\u0466\u0001\u0000\u0000\u0000\u0466\u0467"+ - "\u0006\u007f\u000b\u0000\u0467\u010f\u0001\u0000\u0000\u0000\u0468\u0469"+ - "\u0003N\u001f\u0000\u0469\u046a\u0001\u0000\u0000\u0000\u046a\u046b\u0006"+ - "\u0080\u000e\u0000\u046b\u046c\u0006\u0080\u000f\u0000\u046c\u046d\u0006"+ - "\u0080\u000f\u0000\u046d\u0111\u0001\u0000\u0000\u0000\u046e\u046f\u0003"+ - "p0\u0000\u046f\u0470\u0001\u0000\u0000\u0000\u0470\u0471\u0006\u0081\u0012"+ - "\u0000\u0471\u0113\u0001\u0000\u0000\u0000\u0472\u0473\u0003t2\u0000\u0473"+ - "\u0474\u0001\u0000\u0000\u0000\u0474\u0475\u0006\u0082\u0011\u0000\u0475"+ - "\u0115\u0001\u0000\u0000\u0000\u0476\u0477\u0003x4\u0000\u0477\u0478\u0001"+ - "\u0000\u0000\u0000\u0478\u0479\u0006\u0083\u0015\u0000\u0479\u0117\u0001"+ - "\u0000\u0000\u0000\u047a\u047b\u0003\u0100x\u0000\u047b\u047c\u0001\u0000"+ - "\u0000\u0000\u047c\u047d\u0006\u0084\u001b\u0000\u047d\u0119\u0001\u0000"+ - "\u0000\u0000\u047e\u047f\u0003\u00e0h\u0000\u047f\u0480\u0001\u0000\u0000"+ - "\u0000\u0480\u0481\u0006\u0085\u0016\u0000\u0481\u011b\u0001\u0000\u0000"+ - "\u0000\u0482\u0483\u0003\u00b8T\u0000\u0483\u0484\u0001\u0000\u0000\u0000"+ - "\u0484\u0485\u0006\u0086\u0019\u0000\u0485\u011d\u0001\u0000\u0000\u0000"+ - "\u0486\u0487\u0003:\u0015\u0000\u0487\u0488\u0001\u0000\u0000\u0000\u0488"+ - "\u0489\u0006\u0087\u000b\u0000\u0489\u011f\u0001\u0000\u0000\u0000\u048a"+ - "\u048b\u0003<\u0016\u0000\u048b\u048c\u0001\u0000\u0000\u0000\u048c\u048d"+ - "\u0006\u0088\u000b\u0000\u048d\u0121\u0001\u0000\u0000\u0000\u048e\u048f"+ - "\u0003>\u0017\u0000\u048f\u0490\u0001\u0000\u0000\u0000\u0490\u0491\u0006"+ - "\u0089\u000b\u0000\u0491\u0123\u0001\u0000\u0000\u0000\u0492\u0493\u0003"+ - "N\u001f\u0000\u0493\u0494\u0001\u0000\u0000\u0000\u0494\u0495\u0006\u008a"+ - "\u000e\u0000\u0495\u0496\u0006\u008a\u000f\u0000\u0496\u0125\u0001\u0000"+ - "\u0000\u0000\u0497\u0498\u0003t2\u0000\u0498\u0499\u0001\u0000\u0000\u0000"+ - "\u0499\u049a\u0006\u008b\u0011\u0000\u049a\u0127\u0001\u0000\u0000\u0000"+ - "\u049b\u049c\u0003x4\u0000\u049c\u049d\u0001\u0000\u0000\u0000\u049d\u049e"+ - "\u0006\u008c\u0015\u0000\u049e\u0129\u0001\u0000\u0000\u0000\u049f\u04a0"+ - "\u0003\u00few\u0000\u04a0\u04a1\u0001\u0000\u0000\u0000\u04a1\u04a2\u0006"+ - "\u008d\u001c\u0000\u04a2\u04a3\u0006\u008d\u001d\u0000\u04a3\u012b\u0001"+ - "\u0000\u0000\u0000\u04a4\u04a5\u0003B\u0019\u0000\u04a5\u04a6\u0001\u0000"+ - "\u0000\u0000\u04a6\u04a7\u0006\u008e\u0014\u0000\u04a7\u012d\u0001\u0000"+ - "\u0000\u0000\u04a8\u04a9\u0003:\u0015\u0000\u04a9\u04aa\u0001\u0000\u0000"+ - "\u0000\u04aa\u04ab\u0006\u008f\u000b\u0000\u04ab\u012f\u0001\u0000\u0000"+ - "\u0000\u04ac\u04ad\u0003<\u0016\u0000\u04ad\u04ae\u0001\u0000\u0000\u0000"+ - "\u04ae\u04af\u0006\u0090\u000b\u0000\u04af\u0131\u0001\u0000\u0000\u0000"+ - "\u04b0\u04b1\u0003>\u0017\u0000\u04b1\u04b2\u0001\u0000\u0000\u0000\u04b2"+ - "\u04b3\u0006\u0091\u000b\u0000\u04b3\u0133\u0001\u0000\u0000\u0000\u04b4"+ - "\u04b5\u0003N\u001f\u0000\u04b5\u04b6\u0001\u0000\u0000\u0000\u04b6\u04b7"+ - "\u0006\u0092\u000e\u0000\u04b7\u04b8\u0006\u0092\u000f\u0000\u04b8\u04b9"+ - "\u0006\u0092\u000f\u0000\u04b9\u0135\u0001\u0000\u0000\u0000\u04ba\u04bb"+ - "\u0003t2\u0000\u04bb\u04bc\u0001\u0000\u0000\u0000\u04bc\u04bd\u0006\u0093"+ - "\u0011\u0000\u04bd\u0137\u0001\u0000\u0000\u0000\u04be\u04bf\u0003x4\u0000"+ - "\u04bf\u04c0\u0001\u0000\u0000\u0000\u04c0\u04c1\u0006\u0094\u0015\u0000"+ - "\u04c1\u0139\u0001\u0000\u0000\u0000\u04c2\u04c3\u0003\u00e0h\u0000\u04c3"+ - "\u04c4\u0001\u0000\u0000\u0000\u04c4\u04c5\u0006\u0095\u0016\u0000\u04c5"+ - "\u013b\u0001\u0000\u0000\u0000\u04c6\u04c7\u0003:\u0015\u0000\u04c7\u04c8"+ - "\u0001\u0000\u0000\u0000\u04c8\u04c9\u0006\u0096\u000b\u0000\u04c9\u013d"+ - "\u0001\u0000\u0000\u0000\u04ca\u04cb\u0003<\u0016\u0000\u04cb\u04cc\u0001"+ - "\u0000\u0000\u0000\u04cc\u04cd\u0006\u0097\u000b\u0000\u04cd\u013f\u0001"+ - "\u0000\u0000\u0000\u04ce\u04cf\u0003>\u0017\u0000\u04cf\u04d0\u0001\u0000"+ - "\u0000\u0000\u04d0\u04d1\u0006\u0098\u000b\u0000\u04d1\u0141\u0001\u0000"+ - "\u0000\u0000\u04d2\u04d3\u0003N\u001f\u0000\u04d3\u04d4\u0001\u0000\u0000"+ - "\u0000\u04d4\u04d5\u0006\u0099\u000e\u0000\u04d5\u04d6\u0006\u0099\u000f"+ - "\u0000\u04d6\u0143\u0001\u0000\u0000\u0000\u04d7\u04d8\u0003x4\u0000\u04d8"+ - "\u04d9\u0001\u0000\u0000\u0000\u04d9\u04da\u0006\u009a\u0015\u0000\u04da"+ - "\u0145\u0001\u0000\u0000\u0000\u04db\u04dc\u0003\u00b8T\u0000\u04dc\u04dd"+ - "\u0001\u0000\u0000\u0000\u04dd\u04de\u0006\u009b\u0019\u0000\u04de\u0147"+ - "\u0001\u0000\u0000\u0000\u04df\u04e0\u0003\u00b4R\u0000\u04e0\u04e1\u0001"+ - "\u0000\u0000\u0000\u04e1\u04e2\u0006\u009c\u001e\u0000\u04e2\u0149\u0001"+ - "\u0000\u0000\u0000\u04e3\u04e4\u0003:\u0015\u0000\u04e4\u04e5\u0001\u0000"+ - "\u0000\u0000\u04e5\u04e6\u0006\u009d\u000b\u0000\u04e6\u014b\u0001\u0000"+ - "\u0000\u0000\u04e7\u04e8\u0003<\u0016\u0000\u04e8\u04e9\u0001\u0000\u0000"+ - "\u0000\u04e9\u04ea\u0006\u009e\u000b\u0000\u04ea\u014d\u0001\u0000\u0000"+ - "\u0000\u04eb\u04ec\u0003>\u0017\u0000\u04ec\u04ed\u0001\u0000\u0000\u0000"+ - "\u04ed\u04ee\u0006\u009f\u000b\u0000\u04ee\u014f\u0001\u0000\u0000\u0000"+ - "\u04ef\u04f0\u0003N\u001f\u0000\u04f0\u04f1\u0001\u0000\u0000\u0000\u04f1"+ - "\u04f2\u0006\u00a0\u000e\u0000\u04f2\u04f3\u0006\u00a0\u000f\u0000\u04f3"+ - "\u0151\u0001\u0000\u0000\u0000\u04f4\u04f5\u0005i\u0000\u0000\u04f5\u04f6"+ - "\u0005n\u0000\u0000\u04f6\u04f7\u0005f\u0000\u0000\u04f7\u04f8\u0005o"+ - "\u0000\u0000\u04f8\u0153\u0001\u0000\u0000\u0000\u04f9\u04fa\u0003:\u0015"+ - "\u0000\u04fa\u04fb\u0001\u0000\u0000\u0000\u04fb\u04fc\u0006\u00a2\u000b"+ - "\u0000\u04fc\u0155\u0001\u0000\u0000\u0000\u04fd\u04fe\u0003<\u0016\u0000"+ - "\u04fe\u04ff\u0001\u0000\u0000\u0000\u04ff\u0500\u0006\u00a3\u000b\u0000"+ - "\u0500\u0157\u0001\u0000\u0000\u0000\u0501\u0502\u0003>\u0017\u0000\u0502"+ - "\u0503\u0001\u0000\u0000\u0000\u0503\u0504\u0006\u00a4\u000b\u0000\u0504"+ - "\u0159\u0001\u0000\u0000\u0000\u0505\u0506\u0003N\u001f\u0000\u0506\u0507"+ - "\u0001\u0000\u0000\u0000\u0507\u0508\u0006\u00a5\u000e\u0000\u0508\u0509"+ - "\u0006\u00a5\u000f\u0000\u0509\u015b\u0001\u0000\u0000\u0000\u050a\u050b"+ - "\u0005f\u0000\u0000\u050b\u050c\u0005u\u0000\u0000\u050c\u050d\u0005n"+ - "\u0000\u0000\u050d\u050e\u0005c\u0000\u0000\u050e\u050f\u0005t\u0000\u0000"+ - "\u050f\u0510\u0005i\u0000\u0000\u0510\u0511\u0005o\u0000\u0000\u0511\u0512"+ - "\u0005n\u0000\u0000\u0512\u0513\u0005s\u0000\u0000\u0513\u015d\u0001\u0000"+ - "\u0000\u0000\u0514\u0515\u0003:\u0015\u0000\u0515\u0516\u0001\u0000\u0000"+ - "\u0000\u0516\u0517\u0006\u00a7\u000b\u0000\u0517\u015f\u0001\u0000\u0000"+ - "\u0000\u0518\u0519\u0003<\u0016\u0000\u0519\u051a\u0001\u0000\u0000\u0000"+ - "\u051a\u051b\u0006\u00a8\u000b\u0000\u051b\u0161\u0001\u0000\u0000\u0000"+ - "\u051c\u051d\u0003>\u0017\u0000\u051d\u051e\u0001\u0000\u0000\u0000\u051e"+ - "\u051f\u0006\u00a9\u000b\u0000\u051f\u0163\u0001\u0000\u0000\u0000\u0520"+ - "\u0521\u0003\u00b2Q\u0000\u0521\u0522\u0001\u0000\u0000\u0000\u0522\u0523"+ - "\u0006\u00aa\u0010\u0000\u0523\u0524\u0006\u00aa\u000f\u0000\u0524\u0165"+ - "\u0001\u0000\u0000\u0000\u0525\u0526\u0005:\u0000\u0000\u0526\u0167\u0001"+ - "\u0000\u0000\u0000\u0527\u052d\u0003Z%\u0000\u0528\u052d\u0003P \u0000"+ - "\u0529\u052d\u0003x4\u0000\u052a\u052d\u0003R!\u0000\u052b\u052d\u0003"+ - "`(\u0000\u052c\u0527\u0001\u0000\u0000\u0000\u052c\u0528\u0001\u0000\u0000"+ - "\u0000\u052c\u0529\u0001\u0000\u0000\u0000\u052c\u052a\u0001\u0000\u0000"+ - "\u0000\u052c\u052b\u0001\u0000\u0000\u0000\u052d\u052e\u0001\u0000\u0000"+ - "\u0000\u052e\u052c\u0001\u0000\u0000\u0000\u052e\u052f\u0001\u0000\u0000"+ - "\u0000\u052f\u0169\u0001\u0000\u0000\u0000\u0530\u0531\u0003:\u0015\u0000"+ - "\u0531\u0532\u0001\u0000\u0000\u0000\u0532\u0533\u0006\u00ad\u000b\u0000"+ - "\u0533\u016b\u0001\u0000\u0000\u0000\u0534\u0535\u0003<\u0016\u0000\u0535"+ - "\u0536\u0001\u0000\u0000\u0000\u0536\u0537\u0006\u00ae\u000b\u0000\u0537"+ - "\u016d\u0001\u0000\u0000\u0000\u0538\u0539\u0003>\u0017\u0000\u0539\u053a"+ - "\u0001\u0000\u0000\u0000\u053a\u053b\u0006\u00af\u000b\u0000\u053b\u016f"+ - "\u0001\u0000\u0000\u0000\u053c\u053d\u0003N\u001f\u0000\u053d\u053e\u0001"+ - "\u0000\u0000\u0000\u053e\u053f\u0006\u00b0\u000e\u0000\u053f\u0540\u0006"+ - "\u00b0\u000f\u0000\u0540\u0171\u0001\u0000\u0000\u0000\u0541\u0542\u0003"+ - "B\u0019\u0000\u0542\u0543\u0001\u0000\u0000\u0000\u0543\u0544\u0006\u00b1"+ - "\u0014\u0000\u0544\u0545\u0006\u00b1\u000f\u0000\u0545\u0546\u0006\u00b1"+ - "\u001f\u0000\u0546\u0173\u0001\u0000\u0000\u0000\u0547\u0548\u0003:\u0015"+ - "\u0000\u0548\u0549\u0001\u0000\u0000\u0000\u0549\u054a\u0006\u00b2\u000b"+ - "\u0000\u054a\u0175\u0001\u0000\u0000\u0000\u054b\u054c\u0003<\u0016\u0000"+ - "\u054c\u054d\u0001\u0000\u0000\u0000\u054d\u054e\u0006\u00b3\u000b\u0000"+ - "\u054e\u0177\u0001\u0000\u0000\u0000\u054f\u0550\u0003>\u0017\u0000\u0550"+ - "\u0551\u0001\u0000\u0000\u0000\u0551\u0552\u0006\u00b4\u000b\u0000\u0552"+ - "\u0179\u0001\u0000\u0000\u0000\u0553\u0554\u0003t2\u0000\u0554\u0555\u0001"+ - "\u0000\u0000\u0000\u0555\u0556\u0006\u00b5\u0011\u0000\u0556\u0557\u0006"+ - "\u00b5\u000f\u0000\u0557\u0558\u0006\u00b5\u0007\u0000\u0558\u017b\u0001"+ - "\u0000\u0000\u0000\u0559\u055a\u0003:\u0015\u0000\u055a\u055b\u0001\u0000"+ - "\u0000\u0000\u055b\u055c\u0006\u00b6\u000b\u0000\u055c\u017d\u0001\u0000"+ - "\u0000\u0000\u055d\u055e\u0003<\u0016\u0000\u055e\u055f\u0001\u0000\u0000"+ - "\u0000\u055f\u0560\u0006\u00b7\u000b\u0000\u0560\u017f\u0001\u0000\u0000"+ - "\u0000\u0561\u0562\u0003>\u0017\u0000\u0562\u0563\u0001\u0000\u0000\u0000"+ - "\u0563\u0564\u0006\u00b8\u000b\u0000\u0564\u0181\u0001\u0000\u0000\u0000"+ - "\u0565\u0566\u0003\u00b8T\u0000\u0566\u0567\u0001\u0000\u0000\u0000\u0567"+ - "\u0568\u0006\u00b9\u000f\u0000\u0568\u0569\u0006\u00b9\u0000\u0000\u0569"+ - "\u056a\u0006\u00b9\u0019\u0000\u056a\u0183\u0001\u0000\u0000\u0000\u056b"+ - "\u056c\u0003\u00b4R\u0000\u056c\u056d\u0001\u0000\u0000\u0000\u056d\u056e"+ - "\u0006\u00ba\u000f\u0000\u056e\u056f\u0006\u00ba\u0000\u0000\u056f\u0570"+ - "\u0006\u00ba\u001e\u0000\u0570\u0185\u0001\u0000\u0000\u0000\u0571\u0572"+ - "\u0003j-\u0000\u0572\u0573\u0001\u0000\u0000\u0000\u0573\u0574\u0006\u00bb"+ - "\u000f\u0000\u0574\u0575\u0006\u00bb\u0000\u0000\u0575\u0576\u0006\u00bb"+ - " \u0000\u0576\u0187\u0001\u0000\u0000\u0000\u0577\u0578\u0003N\u001f\u0000"+ - "\u0578\u0579\u0001\u0000\u0000\u0000\u0579\u057a\u0006\u00bc\u000e\u0000"+ - "\u057a\u057b\u0006\u00bc\u000f\u0000\u057b\u0189\u0001\u0000\u0000\u0000"+ - ">\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e"+ - "\u000f\u0236\u0240\u0244\u0247\u0250\u0252\u025d\u0264\u0269\u0290\u0295"+ - "\u029e\u02a5\u02aa\u02ac\u02b7\u02bf\u02c2\u02c4\u02c9\u02ce\u02d4\u02db"+ - "\u02e0\u02e6\u02e9\u02f1\u02f5\u037a\u037f\u0384\u0386\u038c\u03e1\u03e5"+ - "\u03ea\u03ef\u03f4\u03f6\u03fa\u03fc\u0449\u044d\u0452\u052c\u052e!\u0005"+ - "\u0002\u0000\u0005\u0004\u0000\u0005\u0006\u0000\u0005\u0001\u0000\u0005"+ - "\u0003\u0000\u0005\b\u0000\u0005\f\u0000\u0005\u000e\u0000\u0005\n\u0000"+ - "\u0005\u0005\u0000\u0005\u000b\u0000\u0000\u0001\u0000\u0007D\u0000\u0005"+ - "\u0000\u0000\u0007\u001d\u0000\u0004\u0000\u0000\u0007E\u0000\u0007&\u0000"+ - "\u0007$\u0000\u0007\u001e\u0000\u0007\u0019\u0000\u0007(\u0000\u0007O"+ - "\u0000\u0005\r\u0000\u0005\u0007\u0000\u0007G\u0000\u0007Y\u0000\u0007"+ - "X\u0000\u0007W\u0000\u0005\t\u0000\u0007F\u0000\u0005\u000f\u0000\u0007"+ - "!\u0000"; + "F\u00b6G\u00b8\u0000\u00baH\u00bcI\u00beJ\u00c0K\u00c2\u0000\u00c4\u0000"+ + "\u00c6\u0000\u00c8\u0000\u00ca\u0000\u00cc\u0000\u00ceL\u00d0\u0000\u00d2"+ + "M\u00d4N\u00d6O\u00d8\u0000\u00da\u0000\u00dc\u0000\u00de\u0000\u00e0"+ + "\u0000\u00e2P\u00e4Q\u00e6R\u00e8S\u00ea\u0000\u00ec\u0000\u00ee\u0000"+ + "\u00f0\u0000\u00f2T\u00f4\u0000\u00f6U\u00f8V\u00faW\u00fc\u0000\u00fe"+ + "\u0000\u0100X\u0102Y\u0104\u0000\u0106Z\u0108\u0000\u010a\u0000\u010c"+ + "[\u010e\\\u0110]\u0112\u0000\u0114\u0000\u0116\u0000\u0118\u0000\u011a"+ + "\u0000\u011c\u0000\u011e\u0000\u0120^\u0122_\u0124`\u0126\u0000\u0128"+ + "\u0000\u012a\u0000\u012c\u0000\u012e\u0000\u0130a\u0132b\u0134c\u0136"+ + "\u0000\u0138\u0000\u013a\u0000\u013c\u0000\u013ed\u0140e\u0142f\u0144"+ + "\u0000\u0146\u0000\u0148\u0000\u014a\u0000\u014cg\u014eh\u0150i\u0152"+ + "\u0000\u0154j\u0156k\u0158l\u015am\u015c\u0000\u015en\u0160o\u0162p\u0164"+ + "q\u0166\u0000\u0168r\u016as\u016ct\u016eu\u0170v\u0172\u0000\u0174\u0000"+ + "\u0176w\u0178x\u017ay\u017c\u0000\u017ez\u0180{\u0182|\u0184\u0000\u0186"+ + "\u0000\u0188\u0000\u018a\u0000\u0010\u0000\u0001\u0002\u0003\u0004\u0005"+ + "\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\r\u0006\u0000\t\n\r\r //[[]"+ + "]\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r \n\u0000\t\n\r\r ,,//==[["+ + "]]``||\u0002\u0000**//\u0001\u000009\u0002\u0000AZaz\u0005\u0000\"\"\\"+ + "\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000EEee\u0002\u0000++--\u0001"+ + "\u0000``\u000b\u0000\t\n\r\r \"#,,//::<<>?\\\\||\u05a8\u0000\u0010\u0001"+ + "\u0000\u0000\u0000\u0000\u0012\u0001\u0000\u0000\u0000\u0000\u0014\u0001"+ + "\u0000\u0000\u0000\u0000\u0016\u0001\u0000\u0000\u0000\u0000\u0018\u0001"+ + "\u0000\u0000\u0000\u0000\u001a\u0001\u0000\u0000\u0000\u0000\u001c\u0001"+ + "\u0000\u0000\u0000\u0000\u001e\u0001\u0000\u0000\u0000\u0000 \u0001\u0000"+ + "\u0000\u0000\u0000\"\u0001\u0000\u0000\u0000\u0000$\u0001\u0000\u0000"+ + "\u0000\u0000&\u0001\u0000\u0000\u0000\u0000(\u0001\u0000\u0000\u0000\u0000"+ + "*\u0001\u0000\u0000\u0000\u0000,\u0001\u0000\u0000\u0000\u0000.\u0001"+ + "\u0000\u0000\u0000\u00000\u0001\u0000\u0000\u0000\u00002\u0001\u0000\u0000"+ + "\u0000\u00004\u0001\u0000\u0000\u0000\u00006\u0001\u0000\u0000\u0000\u0000"+ + "8\u0001\u0000\u0000\u0000\u0000:\u0001\u0000\u0000\u0000\u0000<\u0001"+ + "\u0000\u0000\u0000\u0000>\u0001\u0000\u0000\u0000\u0000B\u0001\u0000\u0000"+ + "\u0000\u0001D\u0001\u0000\u0000\u0000\u0001F\u0001\u0000\u0000\u0000\u0001"+ + "H\u0001\u0000\u0000\u0000\u0001J\u0001\u0000\u0000\u0000\u0001L\u0001"+ + "\u0000\u0000\u0000\u0002N\u0001\u0000\u0000\u0000\u0002d\u0001\u0000\u0000"+ + "\u0000\u0002f\u0001\u0000\u0000\u0000\u0002h\u0001\u0000\u0000\u0000\u0002"+ + "j\u0001\u0000\u0000\u0000\u0002l\u0001\u0000\u0000\u0000\u0002n\u0001"+ + "\u0000\u0000\u0000\u0002p\u0001\u0000\u0000\u0000\u0002r\u0001\u0000\u0000"+ + "\u0000\u0002t\u0001\u0000\u0000\u0000\u0002v\u0001\u0000\u0000\u0000\u0002"+ + "x\u0001\u0000\u0000\u0000\u0002z\u0001\u0000\u0000\u0000\u0002|\u0001"+ + "\u0000\u0000\u0000\u0002~\u0001\u0000\u0000\u0000\u0002\u0080\u0001\u0000"+ + "\u0000\u0000\u0002\u0082\u0001\u0000\u0000\u0000\u0002\u0084\u0001\u0000"+ + "\u0000\u0000\u0002\u0086\u0001\u0000\u0000\u0000\u0002\u0088\u0001\u0000"+ + "\u0000\u0000\u0002\u008a\u0001\u0000\u0000\u0000\u0002\u008c\u0001\u0000"+ + "\u0000\u0000\u0002\u008e\u0001\u0000\u0000\u0000\u0002\u0090\u0001\u0000"+ + "\u0000\u0000\u0002\u0092\u0001\u0000\u0000\u0000\u0002\u0094\u0001\u0000"+ + "\u0000\u0000\u0002\u0096\u0001\u0000\u0000\u0000\u0002\u0098\u0001\u0000"+ + "\u0000\u0000\u0002\u009a\u0001\u0000\u0000\u0000\u0002\u009c\u0001\u0000"+ + "\u0000\u0000\u0002\u009e\u0001\u0000\u0000\u0000\u0002\u00a0\u0001\u0000"+ + "\u0000\u0000\u0002\u00a2\u0001\u0000\u0000\u0000\u0002\u00a4\u0001\u0000"+ + "\u0000\u0000\u0002\u00a6\u0001\u0000\u0000\u0000\u0002\u00a8\u0001\u0000"+ + "\u0000\u0000\u0002\u00aa\u0001\u0000\u0000\u0000\u0002\u00ac\u0001\u0000"+ + "\u0000\u0000\u0002\u00ae\u0001\u0000\u0000\u0000\u0002\u00b0\u0001\u0000"+ + "\u0000\u0000\u0002\u00b2\u0001\u0000\u0000\u0000\u0002\u00b4\u0001\u0000"+ + "\u0000\u0000\u0002\u00b6\u0001\u0000\u0000\u0000\u0002\u00ba\u0001\u0000"+ + "\u0000\u0000\u0002\u00bc\u0001\u0000\u0000\u0000\u0002\u00be\u0001\u0000"+ + "\u0000\u0000\u0002\u00c0\u0001\u0000\u0000\u0000\u0003\u00c2\u0001\u0000"+ + "\u0000\u0000\u0003\u00c4\u0001\u0000\u0000\u0000\u0003\u00c6\u0001\u0000"+ + "\u0000\u0000\u0003\u00c8\u0001\u0000\u0000\u0000\u0003\u00ca\u0001\u0000"+ + "\u0000\u0000\u0003\u00cc\u0001\u0000\u0000\u0000\u0003\u00ce\u0001\u0000"+ + "\u0000\u0000\u0003\u00d0\u0001\u0000\u0000\u0000\u0003\u00d2\u0001\u0000"+ + "\u0000\u0000\u0003\u00d4\u0001\u0000\u0000\u0000\u0003\u00d6\u0001\u0000"+ + "\u0000\u0000\u0004\u00d8\u0001\u0000\u0000\u0000\u0004\u00da\u0001\u0000"+ + "\u0000\u0000\u0004\u00dc\u0001\u0000\u0000\u0000\u0004\u00e2\u0001\u0000"+ + "\u0000\u0000\u0004\u00e4\u0001\u0000\u0000\u0000\u0004\u00e6\u0001\u0000"+ + "\u0000\u0000\u0004\u00e8\u0001\u0000\u0000\u0000\u0005\u00ea\u0001\u0000"+ + "\u0000\u0000\u0005\u00ec\u0001\u0000\u0000\u0000\u0005\u00ee\u0001\u0000"+ + "\u0000\u0000\u0005\u00f0\u0001\u0000\u0000\u0000\u0005\u00f2\u0001\u0000"+ + "\u0000\u0000\u0005\u00f4\u0001\u0000\u0000\u0000\u0005\u00f6\u0001\u0000"+ + "\u0000\u0000\u0005\u00f8\u0001\u0000\u0000\u0000\u0005\u00fa\u0001\u0000"+ + "\u0000\u0000\u0006\u00fc\u0001\u0000\u0000\u0000\u0006\u00fe\u0001\u0000"+ + "\u0000\u0000\u0006\u0100\u0001\u0000\u0000\u0000\u0006\u0102\u0001\u0000"+ + "\u0000\u0000\u0006\u0106\u0001\u0000\u0000\u0000\u0006\u0108\u0001\u0000"+ + "\u0000\u0000\u0006\u010a\u0001\u0000\u0000\u0000\u0006\u010c\u0001\u0000"+ + "\u0000\u0000\u0006\u010e\u0001\u0000\u0000\u0000\u0006\u0110\u0001\u0000"+ + "\u0000\u0000\u0007\u0112\u0001\u0000\u0000\u0000\u0007\u0114\u0001\u0000"+ + "\u0000\u0000\u0007\u0116\u0001\u0000\u0000\u0000\u0007\u0118\u0001\u0000"+ + "\u0000\u0000\u0007\u011a\u0001\u0000\u0000\u0000\u0007\u011c\u0001\u0000"+ + "\u0000\u0000\u0007\u011e\u0001\u0000\u0000\u0000\u0007\u0120\u0001\u0000"+ + "\u0000\u0000\u0007\u0122\u0001\u0000\u0000\u0000\u0007\u0124\u0001\u0000"+ + "\u0000\u0000\b\u0126\u0001\u0000\u0000\u0000\b\u0128\u0001\u0000\u0000"+ + "\u0000\b\u012a\u0001\u0000\u0000\u0000\b\u012c\u0001\u0000\u0000\u0000"+ + "\b\u012e\u0001\u0000\u0000\u0000\b\u0130\u0001\u0000\u0000\u0000\b\u0132"+ + "\u0001\u0000\u0000\u0000\b\u0134\u0001\u0000\u0000\u0000\t\u0136\u0001"+ + "\u0000\u0000\u0000\t\u0138\u0001\u0000\u0000\u0000\t\u013a\u0001\u0000"+ + "\u0000\u0000\t\u013c\u0001\u0000\u0000\u0000\t\u013e\u0001\u0000\u0000"+ + "\u0000\t\u0140\u0001\u0000\u0000\u0000\t\u0142\u0001\u0000\u0000\u0000"+ + "\n\u0144\u0001\u0000\u0000\u0000\n\u0146\u0001\u0000\u0000\u0000\n\u0148"+ + "\u0001\u0000\u0000\u0000\n\u014a\u0001\u0000\u0000\u0000\n\u014c\u0001"+ + "\u0000\u0000\u0000\n\u014e\u0001\u0000\u0000\u0000\n\u0150\u0001\u0000"+ + "\u0000\u0000\u000b\u0152\u0001\u0000\u0000\u0000\u000b\u0154\u0001\u0000"+ + "\u0000\u0000\u000b\u0156\u0001\u0000\u0000\u0000\u000b\u0158\u0001\u0000"+ + "\u0000\u0000\u000b\u015a\u0001\u0000\u0000\u0000\f\u015c\u0001\u0000\u0000"+ + "\u0000\f\u015e\u0001\u0000\u0000\u0000\f\u0160\u0001\u0000\u0000\u0000"+ + "\f\u0162\u0001\u0000\u0000\u0000\f\u0164\u0001\u0000\u0000\u0000\r\u0166"+ + "\u0001\u0000\u0000\u0000\r\u0168\u0001\u0000\u0000\u0000\r\u016a\u0001"+ + "\u0000\u0000\u0000\r\u016c\u0001\u0000\u0000\u0000\r\u016e\u0001\u0000"+ + "\u0000\u0000\r\u0170\u0001\u0000\u0000\u0000\u000e\u0172\u0001\u0000\u0000"+ + "\u0000\u000e\u0174\u0001\u0000\u0000\u0000\u000e\u0176\u0001\u0000\u0000"+ + "\u0000\u000e\u0178\u0001\u0000\u0000\u0000\u000e\u017a\u0001\u0000\u0000"+ + "\u0000\u000f\u017c\u0001\u0000\u0000\u0000\u000f\u017e\u0001\u0000\u0000"+ + "\u0000\u000f\u0180\u0001\u0000\u0000\u0000\u000f\u0182\u0001\u0000\u0000"+ + "\u0000\u000f\u0184\u0001\u0000\u0000\u0000\u000f\u0186\u0001\u0000\u0000"+ + "\u0000\u000f\u0188\u0001\u0000\u0000\u0000\u000f\u018a\u0001\u0000\u0000"+ + "\u0000\u0010\u018c\u0001\u0000\u0000\u0000\u0012\u0196\u0001\u0000\u0000"+ + "\u0000\u0014\u019d\u0001\u0000\u0000\u0000\u0016\u01a6\u0001\u0000\u0000"+ + "\u0000\u0018\u01ad\u0001\u0000\u0000\u0000\u001a\u01b7\u0001\u0000\u0000"+ + "\u0000\u001c\u01be\u0001\u0000\u0000\u0000\u001e\u01c5\u0001\u0000\u0000"+ + "\u0000 \u01d3\u0001\u0000\u0000\u0000\"\u01da\u0001\u0000\u0000\u0000"+ + "$\u01e2\u0001\u0000\u0000\u0000&\u01eb\u0001\u0000\u0000\u0000(\u01f2"+ + "\u0001\u0000\u0000\u0000*\u01fc\u0001\u0000\u0000\u0000,\u0208\u0001\u0000"+ + "\u0000\u0000.\u0211\u0001\u0000\u0000\u00000\u0217\u0001\u0000\u0000\u0000"+ + "2\u021e\u0001\u0000\u0000\u00004\u0225\u0001\u0000\u0000\u00006\u022d"+ + "\u0001\u0000\u0000\u00008\u0236\u0001\u0000\u0000\u0000:\u023c\u0001\u0000"+ + "\u0000\u0000<\u024d\u0001\u0000\u0000\u0000>\u025d\u0001\u0000\u0000\u0000"+ + "@\u0266\u0001\u0000\u0000\u0000B\u0269\u0001\u0000\u0000\u0000D\u026d"+ + "\u0001\u0000\u0000\u0000F\u0272\u0001\u0000\u0000\u0000H\u0277\u0001\u0000"+ + "\u0000\u0000J\u027b\u0001\u0000\u0000\u0000L\u027f\u0001\u0000\u0000\u0000"+ + "N\u0283\u0001\u0000\u0000\u0000P\u0287\u0001\u0000\u0000\u0000R\u0289"+ + "\u0001\u0000\u0000\u0000T\u028b\u0001\u0000\u0000\u0000V\u028e\u0001\u0000"+ + "\u0000\u0000X\u0290\u0001\u0000\u0000\u0000Z\u0299\u0001\u0000\u0000\u0000"+ + "\\\u029b\u0001\u0000\u0000\u0000^\u02a0\u0001\u0000\u0000\u0000`\u02a2"+ + "\u0001\u0000\u0000\u0000b\u02a7\u0001\u0000\u0000\u0000d\u02c6\u0001\u0000"+ + "\u0000\u0000f\u02c9\u0001\u0000\u0000\u0000h\u02f7\u0001\u0000\u0000\u0000"+ + "j\u02f9\u0001\u0000\u0000\u0000l\u02fc\u0001\u0000\u0000\u0000n\u0300"+ + "\u0001\u0000\u0000\u0000p\u0304\u0001\u0000\u0000\u0000r\u0306\u0001\u0000"+ + "\u0000\u0000t\u0309\u0001\u0000\u0000\u0000v\u030b\u0001\u0000\u0000\u0000"+ + "x\u0310\u0001\u0000\u0000\u0000z\u0312\u0001\u0000\u0000\u0000|\u0318"+ + "\u0001\u0000\u0000\u0000~\u031e\u0001\u0000\u0000\u0000\u0080\u0323\u0001"+ + "\u0000\u0000\u0000\u0082\u0325\u0001\u0000\u0000\u0000\u0084\u0328\u0001"+ + "\u0000\u0000\u0000\u0086\u032b\u0001\u0000\u0000\u0000\u0088\u0330\u0001"+ + "\u0000\u0000\u0000\u008a\u0334\u0001\u0000\u0000\u0000\u008c\u0339\u0001"+ + "\u0000\u0000\u0000\u008e\u033f\u0001\u0000\u0000\u0000\u0090\u0342\u0001"+ + "\u0000\u0000\u0000\u0092\u0344\u0001\u0000\u0000\u0000\u0094\u034a\u0001"+ + "\u0000\u0000\u0000\u0096\u034c\u0001\u0000\u0000\u0000\u0098\u0351\u0001"+ + "\u0000\u0000\u0000\u009a\u0354\u0001\u0000\u0000\u0000\u009c\u0357\u0001"+ + "\u0000\u0000\u0000\u009e\u035a\u0001\u0000\u0000\u0000\u00a0\u035c\u0001"+ + "\u0000\u0000\u0000\u00a2\u035f\u0001\u0000\u0000\u0000\u00a4\u0361\u0001"+ + "\u0000\u0000\u0000\u00a6\u0364\u0001\u0000\u0000\u0000\u00a8\u0366\u0001"+ + "\u0000\u0000\u0000\u00aa\u0368\u0001\u0000\u0000\u0000\u00ac\u036a\u0001"+ + "\u0000\u0000\u0000\u00ae\u036c\u0001\u0000\u0000\u0000\u00b0\u037c\u0001"+ + "\u0000\u0000\u0000\u00b2\u037e\u0001\u0000\u0000\u0000\u00b4\u0383\u0001"+ + "\u0000\u0000\u0000\u00b6\u0398\u0001\u0000\u0000\u0000\u00b8\u039a\u0001"+ + "\u0000\u0000\u0000\u00ba\u03a2\u0001\u0000\u0000\u0000\u00bc\u03a4\u0001"+ + "\u0000\u0000\u0000\u00be\u03a8\u0001\u0000\u0000\u0000\u00c0\u03ac\u0001"+ + "\u0000\u0000\u0000\u00c2\u03b0\u0001\u0000\u0000\u0000\u00c4\u03b5\u0001"+ + "\u0000\u0000\u0000\u00c6\u03b9\u0001\u0000\u0000\u0000\u00c8\u03bd\u0001"+ + "\u0000\u0000\u0000\u00ca\u03c1\u0001\u0000\u0000\u0000\u00cc\u03c5\u0001"+ + "\u0000\u0000\u0000\u00ce\u03c9\u0001\u0000\u0000\u0000\u00d0\u03d2\u0001"+ + "\u0000\u0000\u0000\u00d2\u03d6\u0001\u0000\u0000\u0000\u00d4\u03da\u0001"+ + "\u0000\u0000\u0000\u00d6\u03de\u0001\u0000\u0000\u0000\u00d8\u03e2\u0001"+ + "\u0000\u0000\u0000\u00da\u03e7\u0001\u0000\u0000\u0000\u00dc\u03eb\u0001"+ + "\u0000\u0000\u0000\u00de\u03f3\u0001\u0000\u0000\u0000\u00e0\u0408\u0001"+ + "\u0000\u0000\u0000\u00e2\u040c\u0001\u0000\u0000\u0000\u00e4\u0410\u0001"+ + "\u0000\u0000\u0000\u00e6\u0414\u0001\u0000\u0000\u0000\u00e8\u0418\u0001"+ + "\u0000\u0000\u0000\u00ea\u041c\u0001\u0000\u0000\u0000\u00ec\u0421\u0001"+ + "\u0000\u0000\u0000\u00ee\u0425\u0001\u0000\u0000\u0000\u00f0\u0429\u0001"+ + "\u0000\u0000\u0000\u00f2\u042d\u0001\u0000\u0000\u0000\u00f4\u0430\u0001"+ + "\u0000\u0000\u0000\u00f6\u0434\u0001\u0000\u0000\u0000\u00f8\u0438\u0001"+ + "\u0000\u0000\u0000\u00fa\u043c\u0001\u0000\u0000\u0000\u00fc\u0440\u0001"+ + "\u0000\u0000\u0000\u00fe\u0445\u0001\u0000\u0000\u0000\u0100\u044a\u0001"+ + "\u0000\u0000\u0000\u0102\u044f\u0001\u0000\u0000\u0000\u0104\u0456\u0001"+ + "\u0000\u0000\u0000\u0106\u045f\u0001\u0000\u0000\u0000\u0108\u0466\u0001"+ + "\u0000\u0000\u0000\u010a\u046a\u0001\u0000\u0000\u0000\u010c\u046e\u0001"+ + "\u0000\u0000\u0000\u010e\u0472\u0001\u0000\u0000\u0000\u0110\u0476\u0001"+ + "\u0000\u0000\u0000\u0112\u047a\u0001\u0000\u0000\u0000\u0114\u0480\u0001"+ + "\u0000\u0000\u0000\u0116\u0484\u0001\u0000\u0000\u0000\u0118\u0488\u0001"+ + "\u0000\u0000\u0000\u011a\u048c\u0001\u0000\u0000\u0000\u011c\u0490\u0001"+ + "\u0000\u0000\u0000\u011e\u0494\u0001\u0000\u0000\u0000\u0120\u0498\u0001"+ + "\u0000\u0000\u0000\u0122\u049c\u0001\u0000\u0000\u0000\u0124\u04a0\u0001"+ + "\u0000\u0000\u0000\u0126\u04a4\u0001\u0000\u0000\u0000\u0128\u04a9\u0001"+ + "\u0000\u0000\u0000\u012a\u04ad\u0001\u0000\u0000\u0000\u012c\u04b1\u0001"+ + "\u0000\u0000\u0000\u012e\u04b6\u0001\u0000\u0000\u0000\u0130\u04ba\u0001"+ + "\u0000\u0000\u0000\u0132\u04be\u0001\u0000\u0000\u0000\u0134\u04c2\u0001"+ + "\u0000\u0000\u0000\u0136\u04c6\u0001\u0000\u0000\u0000\u0138\u04cc\u0001"+ + "\u0000\u0000\u0000\u013a\u04d0\u0001\u0000\u0000\u0000\u013c\u04d4\u0001"+ + "\u0000\u0000\u0000\u013e\u04d8\u0001\u0000\u0000\u0000\u0140\u04dc\u0001"+ + "\u0000\u0000\u0000\u0142\u04e0\u0001\u0000\u0000\u0000\u0144\u04e4\u0001"+ + "\u0000\u0000\u0000\u0146\u04e9\u0001\u0000\u0000\u0000\u0148\u04ed\u0001"+ + "\u0000\u0000\u0000\u014a\u04f1\u0001\u0000\u0000\u0000\u014c\u04f5\u0001"+ + "\u0000\u0000\u0000\u014e\u04f9\u0001\u0000\u0000\u0000\u0150\u04fd\u0001"+ + "\u0000\u0000\u0000\u0152\u0501\u0001\u0000\u0000\u0000\u0154\u0506\u0001"+ + "\u0000\u0000\u0000\u0156\u050b\u0001\u0000\u0000\u0000\u0158\u050f\u0001"+ + "\u0000\u0000\u0000\u015a\u0513\u0001\u0000\u0000\u0000\u015c\u0517\u0001"+ + "\u0000\u0000\u0000\u015e\u051c\u0001\u0000\u0000\u0000\u0160\u0526\u0001"+ + "\u0000\u0000\u0000\u0162\u052a\u0001\u0000\u0000\u0000\u0164\u052e\u0001"+ + "\u0000\u0000\u0000\u0166\u0532\u0001\u0000\u0000\u0000\u0168\u0537\u0001"+ + "\u0000\u0000\u0000\u016a\u053e\u0001\u0000\u0000\u0000\u016c\u0542\u0001"+ + "\u0000\u0000\u0000\u016e\u0546\u0001\u0000\u0000\u0000\u0170\u054a\u0001"+ + "\u0000\u0000\u0000\u0172\u054e\u0001\u0000\u0000\u0000\u0174\u0553\u0001"+ + "\u0000\u0000\u0000\u0176\u0559\u0001\u0000\u0000\u0000\u0178\u055d\u0001"+ + "\u0000\u0000\u0000\u017a\u0561\u0001\u0000\u0000\u0000\u017c\u0565\u0001"+ + "\u0000\u0000\u0000\u017e\u056b\u0001\u0000\u0000\u0000\u0180\u056f\u0001"+ + "\u0000\u0000\u0000\u0182\u0573\u0001\u0000\u0000\u0000\u0184\u0577\u0001"+ + "\u0000\u0000\u0000\u0186\u057d\u0001\u0000\u0000\u0000\u0188\u0583\u0001"+ + "\u0000\u0000\u0000\u018a\u0589\u0001\u0000\u0000\u0000\u018c\u018d\u0005"+ + "d\u0000\u0000\u018d\u018e\u0005i\u0000\u0000\u018e\u018f\u0005s\u0000"+ + "\u0000\u018f\u0190\u0005s\u0000\u0000\u0190\u0191\u0005e\u0000\u0000\u0191"+ + "\u0192\u0005c\u0000\u0000\u0192\u0193\u0005t\u0000\u0000\u0193\u0194\u0001"+ + "\u0000\u0000\u0000\u0194\u0195\u0006\u0000\u0000\u0000\u0195\u0011\u0001"+ + "\u0000\u0000\u0000\u0196\u0197\u0005d\u0000\u0000\u0197\u0198\u0005r\u0000"+ + "\u0000\u0198\u0199\u0005o\u0000\u0000\u0199\u019a\u0005p\u0000\u0000\u019a"+ + "\u019b\u0001\u0000\u0000\u0000\u019b\u019c\u0006\u0001\u0001\u0000\u019c"+ + "\u0013\u0001\u0000\u0000\u0000\u019d\u019e\u0005e\u0000\u0000\u019e\u019f"+ + "\u0005n\u0000\u0000\u019f\u01a0\u0005r\u0000\u0000\u01a0\u01a1\u0005i"+ + "\u0000\u0000\u01a1\u01a2\u0005c\u0000\u0000\u01a2\u01a3\u0005h\u0000\u0000"+ + "\u01a3\u01a4\u0001\u0000\u0000\u0000\u01a4\u01a5\u0006\u0002\u0002\u0000"+ + "\u01a5\u0015\u0001\u0000\u0000\u0000\u01a6\u01a7\u0005e\u0000\u0000\u01a7"+ + "\u01a8\u0005v\u0000\u0000\u01a8\u01a9\u0005a\u0000\u0000\u01a9\u01aa\u0005"+ + "l\u0000\u0000\u01aa\u01ab\u0001\u0000\u0000\u0000\u01ab\u01ac\u0006\u0003"+ + "\u0000\u0000\u01ac\u0017\u0001\u0000\u0000\u0000\u01ad\u01ae\u0005e\u0000"+ + "\u0000\u01ae\u01af\u0005x\u0000\u0000\u01af\u01b0\u0005p\u0000\u0000\u01b0"+ + "\u01b1\u0005l\u0000\u0000\u01b1\u01b2\u0005a\u0000\u0000\u01b2\u01b3\u0005"+ + "i\u0000\u0000\u01b3\u01b4\u0005n\u0000\u0000\u01b4\u01b5\u0001\u0000\u0000"+ + "\u0000\u01b5\u01b6\u0006\u0004\u0003\u0000\u01b6\u0019\u0001\u0000\u0000"+ + "\u0000\u01b7\u01b8\u0005f\u0000\u0000\u01b8\u01b9\u0005r\u0000\u0000\u01b9"+ + "\u01ba\u0005o\u0000\u0000\u01ba\u01bb\u0005m\u0000\u0000\u01bb\u01bc\u0001"+ + "\u0000\u0000\u0000\u01bc\u01bd\u0006\u0005\u0004\u0000\u01bd\u001b\u0001"+ + "\u0000\u0000\u0000\u01be\u01bf\u0005g\u0000\u0000\u01bf\u01c0\u0005r\u0000"+ + "\u0000\u01c0\u01c1\u0005o\u0000\u0000\u01c1\u01c2\u0005k\u0000\u0000\u01c2"+ + "\u01c3\u0001\u0000\u0000\u0000\u01c3\u01c4\u0006\u0006\u0000\u0000\u01c4"+ + "\u001d\u0001\u0000\u0000\u0000\u01c5\u01c6\u0005i\u0000\u0000\u01c6\u01c7"+ + "\u0005n\u0000\u0000\u01c7\u01c8\u0005l\u0000\u0000\u01c8\u01c9\u0005i"+ + "\u0000\u0000\u01c9\u01ca\u0005n\u0000\u0000\u01ca\u01cb\u0005e\u0000\u0000"+ + "\u01cb\u01cc\u0005s\u0000\u0000\u01cc\u01cd\u0005t\u0000\u0000\u01cd\u01ce"+ + "\u0005a\u0000\u0000\u01ce\u01cf\u0005t\u0000\u0000\u01cf\u01d0\u0005s"+ + "\u0000\u0000\u01d0\u01d1\u0001\u0000\u0000\u0000\u01d1\u01d2\u0006\u0007"+ + "\u0000\u0000\u01d2\u001f\u0001\u0000\u0000\u0000\u01d3\u01d4\u0005k\u0000"+ + "\u0000\u01d4\u01d5\u0005e\u0000\u0000\u01d5\u01d6\u0005e\u0000\u0000\u01d6"+ + "\u01d7\u0005p\u0000\u0000\u01d7\u01d8\u0001\u0000\u0000\u0000\u01d8\u01d9"+ + "\u0006\b\u0001\u0000\u01d9!\u0001\u0000\u0000\u0000\u01da\u01db\u0005"+ + "l\u0000\u0000\u01db\u01dc\u0005i\u0000\u0000\u01dc\u01dd\u0005m\u0000"+ + "\u0000\u01dd\u01de\u0005i\u0000\u0000\u01de\u01df\u0005t\u0000\u0000\u01df"+ + "\u01e0\u0001\u0000\u0000\u0000\u01e0\u01e1\u0006\t\u0000\u0000\u01e1#"+ + "\u0001\u0000\u0000\u0000\u01e2\u01e3\u0005l\u0000\u0000\u01e3\u01e4\u0005"+ + "o\u0000\u0000\u01e4\u01e5\u0005o\u0000\u0000\u01e5\u01e6\u0005k\u0000"+ + "\u0000\u01e6\u01e7\u0005u\u0000\u0000\u01e7\u01e8\u0005p\u0000\u0000\u01e8"+ + "\u01e9\u0001\u0000\u0000\u0000\u01e9\u01ea\u0006\n\u0005\u0000\u01ea%"+ + "\u0001\u0000\u0000\u0000\u01eb\u01ec\u0005m\u0000\u0000\u01ec\u01ed\u0005"+ + "e\u0000\u0000\u01ed\u01ee\u0005t\u0000\u0000\u01ee\u01ef\u0005a\u0000"+ + "\u0000\u01ef\u01f0\u0001\u0000\u0000\u0000\u01f0\u01f1\u0006\u000b\u0006"+ + "\u0000\u01f1\'\u0001\u0000\u0000\u0000\u01f2\u01f3\u0005m\u0000\u0000"+ + "\u01f3\u01f4\u0005e\u0000\u0000\u01f4\u01f5\u0005t\u0000\u0000\u01f5\u01f6"+ + "\u0005r\u0000\u0000\u01f6\u01f7\u0005i\u0000\u0000\u01f7\u01f8\u0005c"+ + "\u0000\u0000\u01f8\u01f9\u0005s\u0000\u0000\u01f9\u01fa\u0001\u0000\u0000"+ + "\u0000\u01fa\u01fb\u0006\f\u0007\u0000\u01fb)\u0001\u0000\u0000\u0000"+ + "\u01fc\u01fd\u0005m\u0000\u0000\u01fd\u01fe\u0005v\u0000\u0000\u01fe\u01ff"+ + "\u0005_\u0000\u0000\u01ff\u0200\u0005e\u0000\u0000\u0200\u0201\u0005x"+ + "\u0000\u0000\u0201\u0202\u0005p\u0000\u0000\u0202\u0203\u0005a\u0000\u0000"+ + "\u0203\u0204\u0005n\u0000\u0000\u0204\u0205\u0005d\u0000\u0000\u0205\u0206"+ + "\u0001\u0000\u0000\u0000\u0206\u0207\u0006\r\b\u0000\u0207+\u0001\u0000"+ + "\u0000\u0000\u0208\u0209\u0005r\u0000\u0000\u0209\u020a\u0005e\u0000\u0000"+ + "\u020a\u020b\u0005n\u0000\u0000\u020b\u020c\u0005a\u0000\u0000\u020c\u020d"+ + "\u0005m\u0000\u0000\u020d\u020e\u0005e\u0000\u0000\u020e\u020f\u0001\u0000"+ + "\u0000\u0000\u020f\u0210\u0006\u000e\t\u0000\u0210-\u0001\u0000\u0000"+ + "\u0000\u0211\u0212\u0005r\u0000\u0000\u0212\u0213\u0005o\u0000\u0000\u0213"+ + "\u0214\u0005w\u0000\u0000\u0214\u0215\u0001\u0000\u0000\u0000\u0215\u0216"+ + "\u0006\u000f\u0000\u0000\u0216/\u0001\u0000\u0000\u0000\u0217\u0218\u0005"+ + "s\u0000\u0000\u0218\u0219\u0005h\u0000\u0000\u0219\u021a\u0005o\u0000"+ + "\u0000\u021a\u021b\u0005w\u0000\u0000\u021b\u021c\u0001\u0000\u0000\u0000"+ + "\u021c\u021d\u0006\u0010\n\u0000\u021d1\u0001\u0000\u0000\u0000\u021e"+ + "\u021f\u0005s\u0000\u0000\u021f\u0220\u0005o\u0000\u0000\u0220\u0221\u0005"+ + "r\u0000\u0000\u0221\u0222\u0005t\u0000\u0000\u0222\u0223\u0001\u0000\u0000"+ + "\u0000\u0223\u0224\u0006\u0011\u0000\u0000\u02243\u0001\u0000\u0000\u0000"+ + "\u0225\u0226\u0005s\u0000\u0000\u0226\u0227\u0005t\u0000\u0000\u0227\u0228"+ + "\u0005a\u0000\u0000\u0228\u0229\u0005t\u0000\u0000\u0229\u022a\u0005s"+ + "\u0000\u0000\u022a\u022b\u0001\u0000\u0000\u0000\u022b\u022c\u0006\u0012"+ + "\u0000\u0000\u022c5\u0001\u0000\u0000\u0000\u022d\u022e\u0005w\u0000\u0000"+ + "\u022e\u022f\u0005h\u0000\u0000\u022f\u0230\u0005e\u0000\u0000\u0230\u0231"+ + "\u0005r\u0000\u0000\u0231\u0232\u0005e\u0000\u0000\u0232\u0233\u0001\u0000"+ + "\u0000\u0000\u0233\u0234\u0006\u0013\u0000\u0000\u02347\u0001\u0000\u0000"+ + "\u0000\u0235\u0237\b\u0000\u0000\u0000\u0236\u0235\u0001\u0000\u0000\u0000"+ + "\u0237\u0238\u0001\u0000\u0000\u0000\u0238\u0236\u0001\u0000\u0000\u0000"+ + "\u0238\u0239\u0001\u0000\u0000\u0000\u0239\u023a\u0001\u0000\u0000\u0000"+ + "\u023a\u023b\u0006\u0014\u0000\u0000\u023b9\u0001\u0000\u0000\u0000\u023c"+ + "\u023d\u0005/\u0000\u0000\u023d\u023e\u0005/\u0000\u0000\u023e\u0242\u0001"+ + "\u0000\u0000\u0000\u023f\u0241\b\u0001\u0000\u0000\u0240\u023f\u0001\u0000"+ + "\u0000\u0000\u0241\u0244\u0001\u0000\u0000\u0000\u0242\u0240\u0001\u0000"+ + "\u0000\u0000\u0242\u0243\u0001\u0000\u0000\u0000\u0243\u0246\u0001\u0000"+ + "\u0000\u0000\u0244\u0242\u0001\u0000\u0000\u0000\u0245\u0247\u0005\r\u0000"+ + "\u0000\u0246\u0245\u0001\u0000\u0000\u0000\u0246\u0247\u0001\u0000\u0000"+ + "\u0000\u0247\u0249\u0001\u0000\u0000\u0000\u0248\u024a\u0005\n\u0000\u0000"+ + "\u0249\u0248\u0001\u0000\u0000\u0000\u0249\u024a\u0001\u0000\u0000\u0000"+ + "\u024a\u024b\u0001\u0000\u0000\u0000\u024b\u024c\u0006\u0015\u000b\u0000"+ + "\u024c;\u0001\u0000\u0000\u0000\u024d\u024e\u0005/\u0000\u0000\u024e\u024f"+ + "\u0005*\u0000\u0000\u024f\u0254\u0001\u0000\u0000\u0000\u0250\u0253\u0003"+ + "<\u0016\u0000\u0251\u0253\t\u0000\u0000\u0000\u0252\u0250\u0001\u0000"+ + "\u0000\u0000\u0252\u0251\u0001\u0000\u0000\u0000\u0253\u0256\u0001\u0000"+ + "\u0000\u0000\u0254\u0255\u0001\u0000\u0000\u0000\u0254\u0252\u0001\u0000"+ + "\u0000\u0000\u0255\u0257\u0001\u0000\u0000\u0000\u0256\u0254\u0001\u0000"+ + "\u0000\u0000\u0257\u0258\u0005*\u0000\u0000\u0258\u0259\u0005/\u0000\u0000"+ + "\u0259\u025a\u0001\u0000\u0000\u0000\u025a\u025b\u0006\u0016\u000b\u0000"+ + "\u025b=\u0001\u0000\u0000\u0000\u025c\u025e\u0007\u0002\u0000\u0000\u025d"+ + "\u025c\u0001\u0000\u0000\u0000\u025e\u025f\u0001\u0000\u0000\u0000\u025f"+ + "\u025d\u0001\u0000\u0000\u0000\u025f\u0260\u0001\u0000\u0000\u0000\u0260"+ + "\u0261\u0001\u0000\u0000\u0000\u0261\u0262\u0006\u0017\u000b\u0000\u0262"+ + "?\u0001\u0000\u0000\u0000\u0263\u0267\b\u0003\u0000\u0000\u0264\u0265"+ + "\u0005/\u0000\u0000\u0265\u0267\b\u0004\u0000\u0000\u0266\u0263\u0001"+ + "\u0000\u0000\u0000\u0266\u0264\u0001\u0000\u0000\u0000\u0267A\u0001\u0000"+ + "\u0000\u0000\u0268\u026a\u0003@\u0018\u0000\u0269\u0268\u0001\u0000\u0000"+ + "\u0000\u026a\u026b\u0001\u0000\u0000\u0000\u026b\u0269\u0001\u0000\u0000"+ + "\u0000\u026b\u026c\u0001\u0000\u0000\u0000\u026cC\u0001\u0000\u0000\u0000"+ + "\u026d\u026e\u0003\u00b2Q\u0000\u026e\u026f\u0001\u0000\u0000\u0000\u026f"+ + "\u0270\u0006\u001a\f\u0000\u0270\u0271\u0006\u001a\r\u0000\u0271E\u0001"+ + "\u0000\u0000\u0000\u0272\u0273\u0003N\u001f\u0000\u0273\u0274\u0001\u0000"+ + "\u0000\u0000\u0274\u0275\u0006\u001b\u000e\u0000\u0275\u0276\u0006\u001b"+ + "\u000f\u0000\u0276G\u0001\u0000\u0000\u0000\u0277\u0278\u0003>\u0017\u0000"+ + "\u0278\u0279\u0001\u0000\u0000\u0000\u0279\u027a\u0006\u001c\u000b\u0000"+ + "\u027aI\u0001\u0000\u0000\u0000\u027b\u027c\u0003:\u0015\u0000\u027c\u027d"+ + "\u0001\u0000\u0000\u0000\u027d\u027e\u0006\u001d\u000b\u0000\u027eK\u0001"+ + "\u0000\u0000\u0000\u027f\u0280\u0003<\u0016\u0000\u0280\u0281\u0001\u0000"+ + "\u0000\u0000\u0281\u0282\u0006\u001e\u000b\u0000\u0282M\u0001\u0000\u0000"+ + "\u0000\u0283\u0284\u0005|\u0000\u0000\u0284\u0285\u0001\u0000\u0000\u0000"+ + "\u0285\u0286\u0006\u001f\u000f\u0000\u0286O\u0001\u0000\u0000\u0000\u0287"+ + "\u0288\u0007\u0005\u0000\u0000\u0288Q\u0001\u0000\u0000\u0000\u0289\u028a"+ + "\u0007\u0006\u0000\u0000\u028aS\u0001\u0000\u0000\u0000\u028b\u028c\u0005"+ + "\\\u0000\u0000\u028c\u028d\u0007\u0007\u0000\u0000\u028dU\u0001\u0000"+ + "\u0000\u0000\u028e\u028f\b\b\u0000\u0000\u028fW\u0001\u0000\u0000\u0000"+ + "\u0290\u0292\u0007\t\u0000\u0000\u0291\u0293\u0007\n\u0000\u0000\u0292"+ + "\u0291\u0001\u0000\u0000\u0000\u0292\u0293\u0001\u0000\u0000\u0000\u0293"+ + "\u0295\u0001\u0000\u0000\u0000\u0294\u0296\u0003P \u0000\u0295\u0294\u0001"+ + "\u0000\u0000\u0000\u0296\u0297\u0001\u0000\u0000\u0000\u0297\u0295\u0001"+ + "\u0000\u0000\u0000\u0297\u0298\u0001\u0000\u0000\u0000\u0298Y\u0001\u0000"+ + "\u0000\u0000\u0299\u029a\u0005@\u0000\u0000\u029a[\u0001\u0000\u0000\u0000"+ + "\u029b\u029c\u0005`\u0000\u0000\u029c]\u0001\u0000\u0000\u0000\u029d\u02a1"+ + "\b\u000b\u0000\u0000\u029e\u029f\u0005`\u0000\u0000\u029f\u02a1\u0005"+ + "`\u0000\u0000\u02a0\u029d\u0001\u0000\u0000\u0000\u02a0\u029e\u0001\u0000"+ + "\u0000\u0000\u02a1_\u0001\u0000\u0000\u0000\u02a2\u02a3\u0005_\u0000\u0000"+ + "\u02a3a\u0001\u0000\u0000\u0000\u02a4\u02a8\u0003R!\u0000\u02a5\u02a8"+ + "\u0003P \u0000\u02a6\u02a8\u0003`(\u0000\u02a7\u02a4\u0001\u0000\u0000"+ + "\u0000\u02a7\u02a5\u0001\u0000\u0000\u0000\u02a7\u02a6\u0001\u0000\u0000"+ + "\u0000\u02a8c\u0001\u0000\u0000\u0000\u02a9\u02ae\u0005\"\u0000\u0000"+ + "\u02aa\u02ad\u0003T\"\u0000\u02ab\u02ad\u0003V#\u0000\u02ac\u02aa\u0001"+ + "\u0000\u0000\u0000\u02ac\u02ab\u0001\u0000\u0000\u0000\u02ad\u02b0\u0001"+ + "\u0000\u0000\u0000\u02ae\u02ac\u0001\u0000\u0000\u0000\u02ae\u02af\u0001"+ + "\u0000\u0000\u0000\u02af\u02b1\u0001\u0000\u0000\u0000\u02b0\u02ae\u0001"+ + "\u0000\u0000\u0000\u02b1\u02c7\u0005\"\u0000\u0000\u02b2\u02b3\u0005\""+ + "\u0000\u0000\u02b3\u02b4\u0005\"\u0000\u0000\u02b4\u02b5\u0005\"\u0000"+ + "\u0000\u02b5\u02b9\u0001\u0000\u0000\u0000\u02b6\u02b8\b\u0001\u0000\u0000"+ + "\u02b7\u02b6\u0001\u0000\u0000\u0000\u02b8\u02bb\u0001\u0000\u0000\u0000"+ + "\u02b9\u02ba\u0001\u0000\u0000\u0000\u02b9\u02b7\u0001\u0000\u0000\u0000"+ + "\u02ba\u02bc\u0001\u0000\u0000\u0000\u02bb\u02b9\u0001\u0000\u0000\u0000"+ + "\u02bc\u02bd\u0005\"\u0000\u0000\u02bd\u02be\u0005\"\u0000\u0000\u02be"+ + "\u02bf\u0005\"\u0000\u0000\u02bf\u02c1\u0001\u0000\u0000\u0000\u02c0\u02c2"+ + "\u0005\"\u0000\u0000\u02c1\u02c0\u0001\u0000\u0000\u0000\u02c1\u02c2\u0001"+ + "\u0000\u0000\u0000\u02c2\u02c4\u0001\u0000\u0000\u0000\u02c3\u02c5\u0005"+ + "\"\u0000\u0000\u02c4\u02c3\u0001\u0000\u0000\u0000\u02c4\u02c5\u0001\u0000"+ + "\u0000\u0000\u02c5\u02c7\u0001\u0000\u0000\u0000\u02c6\u02a9\u0001\u0000"+ + "\u0000\u0000\u02c6\u02b2\u0001\u0000\u0000\u0000\u02c7e\u0001\u0000\u0000"+ + "\u0000\u02c8\u02ca\u0003P \u0000\u02c9\u02c8\u0001\u0000\u0000\u0000\u02ca"+ + "\u02cb\u0001\u0000\u0000\u0000\u02cb\u02c9\u0001\u0000\u0000\u0000\u02cb"+ + "\u02cc\u0001\u0000\u0000\u0000\u02ccg\u0001\u0000\u0000\u0000\u02cd\u02cf"+ + "\u0003P \u0000\u02ce\u02cd\u0001\u0000\u0000\u0000\u02cf\u02d0\u0001\u0000"+ + "\u0000\u0000\u02d0\u02ce\u0001\u0000\u0000\u0000\u02d0\u02d1\u0001\u0000"+ + "\u0000\u0000\u02d1\u02d2\u0001\u0000\u0000\u0000\u02d2\u02d6\u0003x4\u0000"+ + "\u02d3\u02d5\u0003P \u0000\u02d4\u02d3\u0001\u0000\u0000\u0000\u02d5\u02d8"+ + "\u0001\u0000\u0000\u0000\u02d6\u02d4\u0001\u0000\u0000\u0000\u02d6\u02d7"+ + "\u0001\u0000\u0000\u0000\u02d7\u02f8\u0001\u0000\u0000\u0000\u02d8\u02d6"+ + "\u0001\u0000\u0000\u0000\u02d9\u02db\u0003x4\u0000\u02da\u02dc\u0003P"+ + " \u0000\u02db\u02da\u0001\u0000\u0000\u0000\u02dc\u02dd\u0001\u0000\u0000"+ + "\u0000\u02dd\u02db\u0001\u0000\u0000\u0000\u02dd\u02de\u0001\u0000\u0000"+ + "\u0000\u02de\u02f8\u0001\u0000\u0000\u0000\u02df\u02e1\u0003P \u0000\u02e0"+ + "\u02df\u0001\u0000\u0000\u0000\u02e1\u02e2\u0001\u0000\u0000\u0000\u02e2"+ + "\u02e0\u0001\u0000\u0000\u0000\u02e2\u02e3\u0001\u0000\u0000\u0000\u02e3"+ + "\u02eb\u0001\u0000\u0000\u0000\u02e4\u02e8\u0003x4\u0000\u02e5\u02e7\u0003"+ + "P \u0000\u02e6\u02e5\u0001\u0000\u0000\u0000\u02e7\u02ea\u0001\u0000\u0000"+ + "\u0000\u02e8\u02e6\u0001\u0000\u0000\u0000\u02e8\u02e9\u0001\u0000\u0000"+ + "\u0000\u02e9\u02ec\u0001\u0000\u0000\u0000\u02ea\u02e8\u0001\u0000\u0000"+ + "\u0000\u02eb\u02e4\u0001\u0000\u0000\u0000\u02eb\u02ec\u0001\u0000\u0000"+ + "\u0000\u02ec\u02ed\u0001\u0000\u0000\u0000\u02ed\u02ee\u0003X$\u0000\u02ee"+ + "\u02f8\u0001\u0000\u0000\u0000\u02ef\u02f1\u0003x4\u0000\u02f0\u02f2\u0003"+ + "P \u0000\u02f1\u02f0\u0001\u0000\u0000\u0000\u02f2\u02f3\u0001\u0000\u0000"+ + "\u0000\u02f3\u02f1\u0001\u0000\u0000\u0000\u02f3\u02f4\u0001\u0000\u0000"+ + "\u0000\u02f4\u02f5\u0001\u0000\u0000\u0000\u02f5\u02f6\u0003X$\u0000\u02f6"+ + "\u02f8\u0001\u0000\u0000\u0000\u02f7\u02ce\u0001\u0000\u0000\u0000\u02f7"+ + "\u02d9\u0001\u0000\u0000\u0000\u02f7\u02e0\u0001\u0000\u0000\u0000\u02f7"+ + "\u02ef\u0001\u0000\u0000\u0000\u02f8i\u0001\u0000\u0000\u0000\u02f9\u02fa"+ + "\u0005b\u0000\u0000\u02fa\u02fb\u0005y\u0000\u0000\u02fbk\u0001\u0000"+ + "\u0000\u0000\u02fc\u02fd\u0005a\u0000\u0000\u02fd\u02fe\u0005n\u0000\u0000"+ + "\u02fe\u02ff\u0005d\u0000\u0000\u02ffm\u0001\u0000\u0000\u0000\u0300\u0301"+ + "\u0005a\u0000\u0000\u0301\u0302\u0005s\u0000\u0000\u0302\u0303\u0005c"+ + "\u0000\u0000\u0303o\u0001\u0000\u0000\u0000\u0304\u0305\u0005=\u0000\u0000"+ + "\u0305q\u0001\u0000\u0000\u0000\u0306\u0307\u0005:\u0000\u0000\u0307\u0308"+ + "\u0005:\u0000\u0000\u0308s\u0001\u0000\u0000\u0000\u0309\u030a\u0005,"+ + "\u0000\u0000\u030au\u0001\u0000\u0000\u0000\u030b\u030c\u0005d\u0000\u0000"+ + "\u030c\u030d\u0005e\u0000\u0000\u030d\u030e\u0005s\u0000\u0000\u030e\u030f"+ + "\u0005c\u0000\u0000\u030fw\u0001\u0000\u0000\u0000\u0310\u0311\u0005."+ + "\u0000\u0000\u0311y\u0001\u0000\u0000\u0000\u0312\u0313\u0005f\u0000\u0000"+ + "\u0313\u0314\u0005a\u0000\u0000\u0314\u0315\u0005l\u0000\u0000\u0315\u0316"+ + "\u0005s\u0000\u0000\u0316\u0317\u0005e\u0000\u0000\u0317{\u0001\u0000"+ + "\u0000\u0000\u0318\u0319\u0005f\u0000\u0000\u0319\u031a\u0005i\u0000\u0000"+ + "\u031a\u031b\u0005r\u0000\u0000\u031b\u031c\u0005s\u0000\u0000\u031c\u031d"+ + "\u0005t\u0000\u0000\u031d}\u0001\u0000\u0000\u0000\u031e\u031f\u0005l"+ + "\u0000\u0000\u031f\u0320\u0005a\u0000\u0000\u0320\u0321\u0005s\u0000\u0000"+ + "\u0321\u0322\u0005t\u0000\u0000\u0322\u007f\u0001\u0000\u0000\u0000\u0323"+ + "\u0324\u0005(\u0000\u0000\u0324\u0081\u0001\u0000\u0000\u0000\u0325\u0326"+ + "\u0005i\u0000\u0000\u0326\u0327\u0005n\u0000\u0000\u0327\u0083\u0001\u0000"+ + "\u0000\u0000\u0328\u0329\u0005i\u0000\u0000\u0329\u032a\u0005s\u0000\u0000"+ + "\u032a\u0085\u0001\u0000\u0000\u0000\u032b\u032c\u0005l\u0000\u0000\u032c"+ + "\u032d\u0005i\u0000\u0000\u032d\u032e\u0005k\u0000\u0000\u032e\u032f\u0005"+ + "e\u0000\u0000\u032f\u0087\u0001\u0000\u0000\u0000\u0330\u0331\u0005n\u0000"+ + "\u0000\u0331\u0332\u0005o\u0000\u0000\u0332\u0333\u0005t\u0000\u0000\u0333"+ + "\u0089\u0001\u0000\u0000\u0000\u0334\u0335\u0005n\u0000\u0000\u0335\u0336"+ + "\u0005u\u0000\u0000\u0336\u0337\u0005l\u0000\u0000\u0337\u0338\u0005l"+ + "\u0000\u0000\u0338\u008b\u0001\u0000\u0000\u0000\u0339\u033a\u0005n\u0000"+ + "\u0000\u033a\u033b\u0005u\u0000\u0000\u033b\u033c\u0005l\u0000\u0000\u033c"+ + "\u033d\u0005l\u0000\u0000\u033d\u033e\u0005s\u0000\u0000\u033e\u008d\u0001"+ + "\u0000\u0000\u0000\u033f\u0340\u0005o\u0000\u0000\u0340\u0341\u0005r\u0000"+ + "\u0000\u0341\u008f\u0001\u0000\u0000\u0000\u0342\u0343\u0005?\u0000\u0000"+ + "\u0343\u0091\u0001\u0000\u0000\u0000\u0344\u0345\u0005r\u0000\u0000\u0345"+ + "\u0346\u0005l\u0000\u0000\u0346\u0347\u0005i\u0000\u0000\u0347\u0348\u0005"+ + "k\u0000\u0000\u0348\u0349\u0005e\u0000\u0000\u0349\u0093\u0001\u0000\u0000"+ + "\u0000\u034a\u034b\u0005)\u0000\u0000\u034b\u0095\u0001\u0000\u0000\u0000"+ + "\u034c\u034d\u0005t\u0000\u0000\u034d\u034e\u0005r\u0000\u0000\u034e\u034f"+ + "\u0005u\u0000\u0000\u034f\u0350\u0005e\u0000\u0000\u0350\u0097\u0001\u0000"+ + "\u0000\u0000\u0351\u0352\u0005=\u0000\u0000\u0352\u0353\u0005=\u0000\u0000"+ + "\u0353\u0099\u0001\u0000\u0000\u0000\u0354\u0355\u0005=\u0000\u0000\u0355"+ + "\u0356\u0005~\u0000\u0000\u0356\u009b\u0001\u0000\u0000\u0000\u0357\u0358"+ + "\u0005!\u0000\u0000\u0358\u0359\u0005=\u0000\u0000\u0359\u009d\u0001\u0000"+ + "\u0000\u0000\u035a\u035b\u0005<\u0000\u0000\u035b\u009f\u0001\u0000\u0000"+ + "\u0000\u035c\u035d\u0005<\u0000\u0000\u035d\u035e\u0005=\u0000\u0000\u035e"+ + "\u00a1\u0001\u0000\u0000\u0000\u035f\u0360\u0005>\u0000\u0000\u0360\u00a3"+ + "\u0001\u0000\u0000\u0000\u0361\u0362\u0005>\u0000\u0000\u0362\u0363\u0005"+ + "=\u0000\u0000\u0363\u00a5\u0001\u0000\u0000\u0000\u0364\u0365\u0005+\u0000"+ + "\u0000\u0365\u00a7\u0001\u0000\u0000\u0000\u0366\u0367\u0005-\u0000\u0000"+ + "\u0367\u00a9\u0001\u0000\u0000\u0000\u0368\u0369\u0005*\u0000\u0000\u0369"+ + "\u00ab\u0001\u0000\u0000\u0000\u036a\u036b\u0005/\u0000\u0000\u036b\u00ad"+ + "\u0001\u0000\u0000\u0000\u036c\u036d\u0005%\u0000\u0000\u036d\u00af\u0001"+ + "\u0000\u0000\u0000\u036e\u036f\u0003\u0090@\u0000\u036f\u0373\u0003R!"+ + "\u0000\u0370\u0372\u0003b)\u0000\u0371\u0370\u0001\u0000\u0000\u0000\u0372"+ + "\u0375\u0001\u0000\u0000\u0000\u0373\u0371\u0001\u0000\u0000\u0000\u0373"+ + "\u0374\u0001\u0000\u0000\u0000\u0374\u037d\u0001\u0000\u0000\u0000\u0375"+ + "\u0373\u0001\u0000\u0000\u0000\u0376\u0378\u0003\u0090@\u0000\u0377\u0379"+ + "\u0003P \u0000\u0378\u0377\u0001\u0000\u0000\u0000\u0379\u037a\u0001\u0000"+ + "\u0000\u0000\u037a\u0378\u0001\u0000\u0000\u0000\u037a\u037b\u0001\u0000"+ + "\u0000\u0000\u037b\u037d\u0001\u0000\u0000\u0000\u037c\u036e\u0001\u0000"+ + "\u0000\u0000\u037c\u0376\u0001\u0000\u0000\u0000\u037d\u00b1\u0001\u0000"+ + "\u0000\u0000\u037e\u037f\u0005[\u0000\u0000\u037f\u0380\u0001\u0000\u0000"+ + "\u0000\u0380\u0381\u0006Q\u0000\u0000\u0381\u0382\u0006Q\u0000\u0000\u0382"+ + "\u00b3\u0001\u0000\u0000\u0000\u0383\u0384\u0005]\u0000\u0000\u0384\u0385"+ + "\u0001\u0000\u0000\u0000\u0385\u0386\u0006R\u000f\u0000\u0386\u0387\u0006"+ + "R\u000f\u0000\u0387\u00b5\u0001\u0000\u0000\u0000\u0388\u038c\u0003R!"+ + "\u0000\u0389\u038b\u0003b)\u0000\u038a\u0389\u0001\u0000\u0000\u0000\u038b"+ + "\u038e\u0001\u0000\u0000\u0000\u038c\u038a\u0001\u0000\u0000\u0000\u038c"+ + "\u038d\u0001\u0000\u0000\u0000\u038d\u0399\u0001\u0000\u0000\u0000\u038e"+ + "\u038c\u0001\u0000\u0000\u0000\u038f\u0392\u0003`(\u0000\u0390\u0392\u0003"+ + "Z%\u0000\u0391\u038f\u0001\u0000\u0000\u0000\u0391\u0390\u0001\u0000\u0000"+ + "\u0000\u0392\u0394\u0001\u0000\u0000\u0000\u0393\u0395\u0003b)\u0000\u0394"+ + "\u0393\u0001\u0000\u0000\u0000\u0395\u0396\u0001\u0000\u0000\u0000\u0396"+ + "\u0394\u0001\u0000\u0000\u0000\u0396\u0397\u0001\u0000\u0000\u0000\u0397"+ + "\u0399\u0001\u0000\u0000\u0000\u0398\u0388\u0001\u0000\u0000\u0000\u0398"+ + "\u0391\u0001\u0000\u0000\u0000\u0399\u00b7\u0001\u0000\u0000\u0000\u039a"+ + "\u039c\u0003\\&\u0000\u039b\u039d\u0003^\'\u0000\u039c\u039b\u0001\u0000"+ + "\u0000\u0000\u039d\u039e\u0001\u0000\u0000\u0000\u039e\u039c\u0001\u0000"+ + "\u0000\u0000\u039e\u039f\u0001\u0000\u0000\u0000\u039f\u03a0\u0001\u0000"+ + "\u0000\u0000\u03a0\u03a1\u0003\\&\u0000\u03a1\u00b9\u0001\u0000\u0000"+ + "\u0000\u03a2\u03a3\u0003\u00b8T\u0000\u03a3\u00bb\u0001\u0000\u0000\u0000"+ + "\u03a4\u03a5\u0003:\u0015\u0000\u03a5\u03a6\u0001\u0000\u0000\u0000\u03a6"+ + "\u03a7\u0006V\u000b\u0000\u03a7\u00bd\u0001\u0000\u0000\u0000\u03a8\u03a9"+ + "\u0003<\u0016\u0000\u03a9\u03aa\u0001\u0000\u0000\u0000\u03aa\u03ab\u0006"+ + "W\u000b\u0000\u03ab\u00bf\u0001\u0000\u0000\u0000\u03ac\u03ad\u0003>\u0017"+ + "\u0000\u03ad\u03ae\u0001\u0000\u0000\u0000\u03ae\u03af\u0006X\u000b\u0000"+ + "\u03af\u00c1\u0001\u0000\u0000\u0000\u03b0\u03b1\u0003N\u001f\u0000\u03b1"+ + "\u03b2\u0001\u0000\u0000\u0000\u03b2\u03b3\u0006Y\u000e\u0000\u03b3\u03b4"+ + "\u0006Y\u000f\u0000\u03b4\u00c3\u0001\u0000\u0000\u0000\u03b5\u03b6\u0003"+ + "\u00b2Q\u0000\u03b6\u03b7\u0001\u0000\u0000\u0000\u03b7\u03b8\u0006Z\f"+ + "\u0000\u03b8\u00c5\u0001\u0000\u0000\u0000\u03b9\u03ba\u0003\u00b4R\u0000"+ + "\u03ba\u03bb\u0001\u0000\u0000\u0000\u03bb\u03bc\u0006[\u0010\u0000\u03bc"+ + "\u00c7\u0001\u0000\u0000\u0000\u03bd\u03be\u0003t2\u0000\u03be\u03bf\u0001"+ + "\u0000\u0000\u0000\u03bf\u03c0\u0006\\\u0011\u0000\u03c0\u00c9\u0001\u0000"+ + "\u0000\u0000\u03c1\u03c2\u0003p0\u0000\u03c2\u03c3\u0001\u0000\u0000\u0000"+ + "\u03c3\u03c4\u0006]\u0012\u0000\u03c4\u00cb\u0001\u0000\u0000\u0000\u03c5"+ + "\u03c6\u0003d*\u0000\u03c6\u03c7\u0001\u0000\u0000\u0000\u03c7\u03c8\u0006"+ + "^\u0013\u0000\u03c8\u00cd\u0001\u0000\u0000\u0000\u03c9\u03ca\u0005m\u0000"+ + "\u0000\u03ca\u03cb\u0005e\u0000\u0000\u03cb\u03cc\u0005t\u0000\u0000\u03cc"+ + "\u03cd\u0005a\u0000\u0000\u03cd\u03ce\u0005d\u0000\u0000\u03ce\u03cf\u0005"+ + "a\u0000\u0000\u03cf\u03d0\u0005t\u0000\u0000\u03d0\u03d1\u0005a\u0000"+ + "\u0000\u03d1\u00cf\u0001\u0000\u0000\u0000\u03d2\u03d3\u0003B\u0019\u0000"+ + "\u03d3\u03d4\u0001\u0000\u0000\u0000\u03d4\u03d5\u0006`\u0014\u0000\u03d5"+ + "\u00d1\u0001\u0000\u0000\u0000\u03d6\u03d7\u0003:\u0015\u0000\u03d7\u03d8"+ + "\u0001\u0000\u0000\u0000\u03d8\u03d9\u0006a\u000b\u0000\u03d9\u00d3\u0001"+ + "\u0000\u0000\u0000\u03da\u03db\u0003<\u0016\u0000\u03db\u03dc\u0001\u0000"+ + "\u0000\u0000\u03dc\u03dd\u0006b\u000b\u0000\u03dd\u00d5\u0001\u0000\u0000"+ + "\u0000\u03de\u03df\u0003>\u0017\u0000\u03df\u03e0\u0001\u0000\u0000\u0000"+ + "\u03e0\u03e1\u0006c\u000b\u0000\u03e1\u00d7\u0001\u0000\u0000\u0000\u03e2"+ + "\u03e3\u0003N\u001f\u0000\u03e3\u03e4\u0001\u0000\u0000\u0000\u03e4\u03e5"+ + "\u0006d\u000e\u0000\u03e5\u03e6\u0006d\u000f\u0000\u03e6\u00d9\u0001\u0000"+ + "\u0000\u0000\u03e7\u03e8\u0003x4\u0000\u03e8\u03e9\u0001\u0000\u0000\u0000"+ + "\u03e9\u03ea\u0006e\u0015\u0000\u03ea\u00db\u0001\u0000\u0000\u0000\u03eb"+ + "\u03ec\u0003t2\u0000\u03ec\u03ed\u0001\u0000\u0000\u0000\u03ed\u03ee\u0006"+ + "f\u0011\u0000\u03ee\u00dd\u0001\u0000\u0000\u0000\u03ef\u03f4\u0003R!"+ + "\u0000\u03f0\u03f4\u0003P \u0000\u03f1\u03f4\u0003`(\u0000\u03f2\u03f4"+ + "\u0003\u00aaM\u0000\u03f3\u03ef\u0001\u0000\u0000\u0000\u03f3\u03f0\u0001"+ + "\u0000\u0000\u0000\u03f3\u03f1\u0001\u0000\u0000\u0000\u03f3\u03f2\u0001"+ + "\u0000\u0000\u0000\u03f4\u00df\u0001\u0000\u0000\u0000\u03f5\u03f8\u0003"+ + "R!\u0000\u03f6\u03f8\u0003\u00aaM\u0000\u03f7\u03f5\u0001\u0000\u0000"+ + "\u0000\u03f7\u03f6\u0001\u0000\u0000\u0000\u03f8\u03fc\u0001\u0000\u0000"+ + "\u0000\u03f9\u03fb\u0003\u00deg\u0000\u03fa\u03f9\u0001\u0000\u0000\u0000"+ + "\u03fb\u03fe\u0001\u0000\u0000\u0000\u03fc\u03fa\u0001\u0000\u0000\u0000"+ + "\u03fc\u03fd\u0001\u0000\u0000\u0000\u03fd\u0409\u0001\u0000\u0000\u0000"+ + "\u03fe\u03fc\u0001\u0000\u0000\u0000\u03ff\u0402\u0003`(\u0000\u0400\u0402"+ + "\u0003Z%\u0000\u0401\u03ff\u0001\u0000\u0000\u0000\u0401\u0400\u0001\u0000"+ + "\u0000\u0000\u0402\u0404\u0001\u0000\u0000\u0000\u0403\u0405\u0003\u00de"+ + "g\u0000\u0404\u0403\u0001\u0000\u0000\u0000\u0405\u0406\u0001\u0000\u0000"+ + "\u0000\u0406\u0404\u0001\u0000\u0000\u0000\u0406\u0407\u0001\u0000\u0000"+ + "\u0000\u0407\u0409\u0001\u0000\u0000\u0000\u0408\u03f7\u0001\u0000\u0000"+ + "\u0000\u0408\u0401\u0001\u0000\u0000\u0000\u0409\u00e1\u0001\u0000\u0000"+ + "\u0000\u040a\u040d\u0003\u00e0h\u0000\u040b\u040d\u0003\u00b8T\u0000\u040c"+ + "\u040a\u0001\u0000\u0000\u0000\u040c\u040b\u0001\u0000\u0000\u0000\u040d"+ + "\u040e\u0001\u0000\u0000\u0000\u040e\u040c\u0001\u0000\u0000\u0000\u040e"+ + "\u040f\u0001\u0000\u0000\u0000\u040f\u00e3\u0001\u0000\u0000\u0000\u0410"+ + "\u0411\u0003:\u0015\u0000\u0411\u0412\u0001\u0000\u0000\u0000\u0412\u0413"+ + "\u0006j\u000b\u0000\u0413\u00e5\u0001\u0000\u0000\u0000\u0414\u0415\u0003"+ + "<\u0016\u0000\u0415\u0416\u0001\u0000\u0000\u0000\u0416\u0417\u0006k\u000b"+ + "\u0000\u0417\u00e7\u0001\u0000\u0000\u0000\u0418\u0419\u0003>\u0017\u0000"+ + "\u0419\u041a\u0001\u0000\u0000\u0000\u041a\u041b\u0006l\u000b\u0000\u041b"+ + "\u00e9\u0001\u0000\u0000\u0000\u041c\u041d\u0003N\u001f\u0000\u041d\u041e"+ + "\u0001\u0000\u0000\u0000\u041e\u041f\u0006m\u000e\u0000\u041f\u0420\u0006"+ + "m\u000f\u0000\u0420\u00eb\u0001\u0000\u0000\u0000\u0421\u0422\u0003p0"+ + "\u0000\u0422\u0423\u0001\u0000\u0000\u0000\u0423\u0424\u0006n\u0012\u0000"+ + "\u0424\u00ed\u0001\u0000\u0000\u0000\u0425\u0426\u0003t2\u0000\u0426\u0427"+ + "\u0001\u0000\u0000\u0000\u0427\u0428\u0006o\u0011\u0000\u0428\u00ef\u0001"+ + "\u0000\u0000\u0000\u0429\u042a\u0003x4\u0000\u042a\u042b\u0001\u0000\u0000"+ + "\u0000\u042b\u042c\u0006p\u0015\u0000\u042c\u00f1\u0001\u0000\u0000\u0000"+ + "\u042d\u042e\u0005a\u0000\u0000\u042e\u042f\u0005s\u0000\u0000\u042f\u00f3"+ + "\u0001\u0000\u0000\u0000\u0430\u0431\u0003\u00e2i\u0000\u0431\u0432\u0001"+ + "\u0000\u0000\u0000\u0432\u0433\u0006r\u0016\u0000\u0433\u00f5\u0001\u0000"+ + "\u0000\u0000\u0434\u0435\u0003:\u0015\u0000\u0435\u0436\u0001\u0000\u0000"+ + "\u0000\u0436\u0437\u0006s\u000b\u0000\u0437\u00f7\u0001\u0000\u0000\u0000"+ + "\u0438\u0439\u0003<\u0016\u0000\u0439\u043a\u0001\u0000\u0000\u0000\u043a"+ + "\u043b\u0006t\u000b\u0000\u043b\u00f9\u0001\u0000\u0000\u0000\u043c\u043d"+ + "\u0003>\u0017\u0000\u043d\u043e\u0001\u0000\u0000\u0000\u043e\u043f\u0006"+ + "u\u000b\u0000\u043f\u00fb\u0001\u0000\u0000\u0000\u0440\u0441\u0003N\u001f"+ + "\u0000\u0441\u0442\u0001\u0000\u0000\u0000\u0442\u0443\u0006v\u000e\u0000"+ + "\u0443\u0444\u0006v\u000f\u0000\u0444\u00fd\u0001\u0000\u0000\u0000\u0445"+ + "\u0446\u0003\u00b2Q\u0000\u0446\u0447\u0001\u0000\u0000\u0000\u0447\u0448"+ + "\u0006w\f\u0000\u0448\u0449\u0006w\u0017\u0000\u0449\u00ff\u0001\u0000"+ + "\u0000\u0000\u044a\u044b\u0005o\u0000\u0000\u044b\u044c\u0005n\u0000\u0000"+ + "\u044c\u044d\u0001\u0000\u0000\u0000\u044d\u044e\u0006x\u0018\u0000\u044e"+ + "\u0101\u0001\u0000\u0000\u0000\u044f\u0450\u0005w\u0000\u0000\u0450\u0451"+ + "\u0005i\u0000\u0000\u0451\u0452\u0005t\u0000\u0000\u0452\u0453\u0005h"+ + "\u0000\u0000\u0453\u0454\u0001\u0000\u0000\u0000\u0454\u0455\u0006y\u0018"+ + "\u0000\u0455\u0103\u0001\u0000\u0000\u0000\u0456\u0457\b\f\u0000\u0000"+ + "\u0457\u0105\u0001\u0000\u0000\u0000\u0458\u045a\u0003\u0104z\u0000\u0459"+ + "\u0458\u0001\u0000\u0000\u0000\u045a\u045b\u0001\u0000\u0000\u0000\u045b"+ + "\u0459\u0001\u0000\u0000\u0000\u045b\u045c\u0001\u0000\u0000\u0000\u045c"+ + "\u045d\u0001\u0000\u0000\u0000\u045d\u045e\u0003\u0168\u00ac\u0000\u045e"+ + "\u0460\u0001\u0000\u0000\u0000\u045f\u0459\u0001\u0000\u0000\u0000\u045f"+ + "\u0460\u0001\u0000\u0000\u0000\u0460\u0462\u0001\u0000\u0000\u0000\u0461"+ + "\u0463\u0003\u0104z\u0000\u0462\u0461\u0001\u0000\u0000\u0000\u0463\u0464"+ + "\u0001\u0000\u0000\u0000\u0464\u0462\u0001\u0000\u0000\u0000\u0464\u0465"+ + "\u0001\u0000\u0000\u0000\u0465\u0107\u0001\u0000\u0000\u0000\u0466\u0467"+ + "\u0003\u00baU\u0000\u0467\u0468\u0001\u0000\u0000\u0000\u0468\u0469\u0006"+ + "|\u0019\u0000\u0469\u0109\u0001\u0000\u0000\u0000\u046a\u046b\u0003\u0106"+ + "{\u0000\u046b\u046c\u0001\u0000\u0000\u0000\u046c\u046d\u0006}\u001a\u0000"+ + "\u046d\u010b\u0001\u0000\u0000\u0000\u046e\u046f\u0003:\u0015\u0000\u046f"+ + "\u0470\u0001\u0000\u0000\u0000\u0470\u0471\u0006~\u000b\u0000\u0471\u010d"+ + "\u0001\u0000\u0000\u0000\u0472\u0473\u0003<\u0016\u0000\u0473\u0474\u0001"+ + "\u0000\u0000\u0000\u0474\u0475\u0006\u007f\u000b\u0000\u0475\u010f\u0001"+ + "\u0000\u0000\u0000\u0476\u0477\u0003>\u0017\u0000\u0477\u0478\u0001\u0000"+ + "\u0000\u0000\u0478\u0479\u0006\u0080\u000b\u0000\u0479\u0111\u0001\u0000"+ + "\u0000\u0000\u047a\u047b\u0003N\u001f\u0000\u047b\u047c\u0001\u0000\u0000"+ + "\u0000\u047c\u047d\u0006\u0081\u000e\u0000\u047d\u047e\u0006\u0081\u000f"+ + "\u0000\u047e\u047f\u0006\u0081\u000f\u0000\u047f\u0113\u0001\u0000\u0000"+ + "\u0000\u0480\u0481\u0003p0\u0000\u0481\u0482\u0001\u0000\u0000\u0000\u0482"+ + "\u0483\u0006\u0082\u0012\u0000\u0483\u0115\u0001\u0000\u0000\u0000\u0484"+ + "\u0485\u0003t2\u0000\u0485\u0486\u0001\u0000\u0000\u0000\u0486\u0487\u0006"+ + "\u0083\u0011\u0000\u0487\u0117\u0001\u0000\u0000\u0000\u0488\u0489\u0003"+ + "x4\u0000\u0489\u048a\u0001\u0000\u0000\u0000\u048a\u048b\u0006\u0084\u0015"+ + "\u0000\u048b\u0119\u0001\u0000\u0000\u0000\u048c\u048d\u0003\u0102y\u0000"+ + "\u048d\u048e\u0001\u0000\u0000\u0000\u048e\u048f\u0006\u0085\u001b\u0000"+ + "\u048f\u011b\u0001\u0000\u0000\u0000\u0490\u0491\u0003\u00e2i\u0000\u0491"+ + "\u0492\u0001\u0000\u0000\u0000\u0492\u0493\u0006\u0086\u0016\u0000\u0493"+ + "\u011d\u0001\u0000\u0000\u0000\u0494\u0495\u0003\u00baU\u0000\u0495\u0496"+ + "\u0001\u0000\u0000\u0000\u0496\u0497\u0006\u0087\u0019\u0000\u0497\u011f"+ + "\u0001\u0000\u0000\u0000\u0498\u0499\u0003:\u0015\u0000\u0499\u049a\u0001"+ + "\u0000\u0000\u0000\u049a\u049b\u0006\u0088\u000b\u0000\u049b\u0121\u0001"+ + "\u0000\u0000\u0000\u049c\u049d\u0003<\u0016\u0000\u049d\u049e\u0001\u0000"+ + "\u0000\u0000\u049e\u049f\u0006\u0089\u000b\u0000\u049f\u0123\u0001\u0000"+ + "\u0000\u0000\u04a0\u04a1\u0003>\u0017\u0000\u04a1\u04a2\u0001\u0000\u0000"+ + "\u0000\u04a2\u04a3\u0006\u008a\u000b\u0000\u04a3\u0125\u0001\u0000\u0000"+ + "\u0000\u04a4\u04a5\u0003N\u001f\u0000\u04a5\u04a6\u0001\u0000\u0000\u0000"+ + "\u04a6\u04a7\u0006\u008b\u000e\u0000\u04a7\u04a8\u0006\u008b\u000f\u0000"+ + "\u04a8\u0127\u0001\u0000\u0000\u0000\u04a9\u04aa\u0003t2\u0000\u04aa\u04ab"+ + "\u0001\u0000\u0000\u0000\u04ab\u04ac\u0006\u008c\u0011\u0000\u04ac\u0129"+ + "\u0001\u0000\u0000\u0000\u04ad\u04ae\u0003x4\u0000\u04ae\u04af\u0001\u0000"+ + "\u0000\u0000\u04af\u04b0\u0006\u008d\u0015\u0000\u04b0\u012b\u0001\u0000"+ + "\u0000\u0000\u04b1\u04b2\u0003\u0100x\u0000\u04b2\u04b3\u0001\u0000\u0000"+ + "\u0000\u04b3\u04b4\u0006\u008e\u001c\u0000\u04b4\u04b5\u0006\u008e\u001d"+ + "\u0000\u04b5\u012d\u0001\u0000\u0000\u0000\u04b6\u04b7\u0003B\u0019\u0000"+ + "\u04b7\u04b8\u0001\u0000\u0000\u0000\u04b8\u04b9\u0006\u008f\u0014\u0000"+ + "\u04b9\u012f\u0001\u0000\u0000\u0000\u04ba\u04bb\u0003:\u0015\u0000\u04bb"+ + "\u04bc\u0001\u0000\u0000\u0000\u04bc\u04bd\u0006\u0090\u000b\u0000\u04bd"+ + "\u0131\u0001\u0000\u0000\u0000\u04be\u04bf\u0003<\u0016\u0000\u04bf\u04c0"+ + "\u0001\u0000\u0000\u0000\u04c0\u04c1\u0006\u0091\u000b\u0000\u04c1\u0133"+ + "\u0001\u0000\u0000\u0000\u04c2\u04c3\u0003>\u0017\u0000\u04c3\u04c4\u0001"+ + "\u0000\u0000\u0000\u04c4\u04c5\u0006\u0092\u000b\u0000\u04c5\u0135\u0001"+ + "\u0000\u0000\u0000\u04c6\u04c7\u0003N\u001f\u0000\u04c7\u04c8\u0001\u0000"+ + "\u0000\u0000\u04c8\u04c9\u0006\u0093\u000e\u0000\u04c9\u04ca\u0006\u0093"+ + "\u000f\u0000\u04ca\u04cb\u0006\u0093\u000f\u0000\u04cb\u0137\u0001\u0000"+ + "\u0000\u0000\u04cc\u04cd\u0003t2\u0000\u04cd\u04ce\u0001\u0000\u0000\u0000"+ + "\u04ce\u04cf\u0006\u0094\u0011\u0000\u04cf\u0139\u0001\u0000\u0000\u0000"+ + "\u04d0\u04d1\u0003x4\u0000\u04d1\u04d2\u0001\u0000\u0000\u0000\u04d2\u04d3"+ + "\u0006\u0095\u0015\u0000\u04d3\u013b\u0001\u0000\u0000\u0000\u04d4\u04d5"+ + "\u0003\u00e2i\u0000\u04d5\u04d6\u0001\u0000\u0000\u0000\u04d6\u04d7\u0006"+ + "\u0096\u0016\u0000\u04d7\u013d\u0001\u0000\u0000\u0000\u04d8\u04d9\u0003"+ + ":\u0015\u0000\u04d9\u04da\u0001\u0000\u0000\u0000\u04da\u04db\u0006\u0097"+ + "\u000b\u0000\u04db\u013f\u0001\u0000\u0000\u0000\u04dc\u04dd\u0003<\u0016"+ + "\u0000\u04dd\u04de\u0001\u0000\u0000\u0000\u04de\u04df\u0006\u0098\u000b"+ + "\u0000\u04df\u0141\u0001\u0000\u0000\u0000\u04e0\u04e1\u0003>\u0017\u0000"+ + "\u04e1\u04e2\u0001\u0000\u0000\u0000\u04e2\u04e3\u0006\u0099\u000b\u0000"+ + "\u04e3\u0143\u0001\u0000\u0000\u0000\u04e4\u04e5\u0003N\u001f\u0000\u04e5"+ + "\u04e6\u0001\u0000\u0000\u0000\u04e6\u04e7\u0006\u009a\u000e\u0000\u04e7"+ + "\u04e8\u0006\u009a\u000f\u0000\u04e8\u0145\u0001\u0000\u0000\u0000\u04e9"+ + "\u04ea\u0003x4\u0000\u04ea\u04eb\u0001\u0000\u0000\u0000\u04eb\u04ec\u0006"+ + "\u009b\u0015\u0000\u04ec\u0147\u0001\u0000\u0000\u0000\u04ed\u04ee\u0003"+ + "\u00baU\u0000\u04ee\u04ef\u0001\u0000\u0000\u0000\u04ef\u04f0\u0006\u009c"+ + "\u0019\u0000\u04f0\u0149\u0001\u0000\u0000\u0000\u04f1\u04f2\u0003\u00b6"+ + "S\u0000\u04f2\u04f3\u0001\u0000\u0000\u0000\u04f3\u04f4\u0006\u009d\u001e"+ + "\u0000\u04f4\u014b\u0001\u0000\u0000\u0000\u04f5\u04f6\u0003:\u0015\u0000"+ + "\u04f6\u04f7\u0001\u0000\u0000\u0000\u04f7\u04f8\u0006\u009e\u000b\u0000"+ + "\u04f8\u014d\u0001\u0000\u0000\u0000\u04f9\u04fa\u0003<\u0016\u0000\u04fa"+ + "\u04fb\u0001\u0000\u0000\u0000\u04fb\u04fc\u0006\u009f\u000b\u0000\u04fc"+ + "\u014f\u0001\u0000\u0000\u0000\u04fd\u04fe\u0003>\u0017\u0000\u04fe\u04ff"+ + "\u0001\u0000\u0000\u0000\u04ff\u0500\u0006\u00a0\u000b\u0000\u0500\u0151"+ + "\u0001\u0000\u0000\u0000\u0501\u0502\u0003N\u001f\u0000\u0502\u0503\u0001"+ + "\u0000\u0000\u0000\u0503\u0504\u0006\u00a1\u000e\u0000\u0504\u0505\u0006"+ + "\u00a1\u000f\u0000\u0505\u0153\u0001\u0000\u0000\u0000\u0506\u0507\u0005"+ + "i\u0000\u0000\u0507\u0508\u0005n\u0000\u0000\u0508\u0509\u0005f\u0000"+ + "\u0000\u0509\u050a\u0005o\u0000\u0000\u050a\u0155\u0001\u0000\u0000\u0000"+ + "\u050b\u050c\u0003:\u0015\u0000\u050c\u050d\u0001\u0000\u0000\u0000\u050d"+ + "\u050e\u0006\u00a3\u000b\u0000\u050e\u0157\u0001\u0000\u0000\u0000\u050f"+ + "\u0510\u0003<\u0016\u0000\u0510\u0511\u0001\u0000\u0000\u0000\u0511\u0512"+ + "\u0006\u00a4\u000b\u0000\u0512\u0159\u0001\u0000\u0000\u0000\u0513\u0514"+ + "\u0003>\u0017\u0000\u0514\u0515\u0001\u0000\u0000\u0000\u0515\u0516\u0006"+ + "\u00a5\u000b\u0000\u0516\u015b\u0001\u0000\u0000\u0000\u0517\u0518\u0003"+ + "N\u001f\u0000\u0518\u0519\u0001\u0000\u0000\u0000\u0519\u051a\u0006\u00a6"+ + "\u000e\u0000\u051a\u051b\u0006\u00a6\u000f\u0000\u051b\u015d\u0001\u0000"+ + "\u0000\u0000\u051c\u051d\u0005f\u0000\u0000\u051d\u051e\u0005u\u0000\u0000"+ + "\u051e\u051f\u0005n\u0000\u0000\u051f\u0520\u0005c\u0000\u0000\u0520\u0521"+ + "\u0005t\u0000\u0000\u0521\u0522\u0005i\u0000\u0000\u0522\u0523\u0005o"+ + "\u0000\u0000\u0523\u0524\u0005n\u0000\u0000\u0524\u0525\u0005s\u0000\u0000"+ + "\u0525\u015f\u0001\u0000\u0000\u0000\u0526\u0527\u0003:\u0015\u0000\u0527"+ + "\u0528\u0001\u0000\u0000\u0000\u0528\u0529\u0006\u00a8\u000b\u0000\u0529"+ + "\u0161\u0001\u0000\u0000\u0000\u052a\u052b\u0003<\u0016\u0000\u052b\u052c"+ + "\u0001\u0000\u0000\u0000\u052c\u052d\u0006\u00a9\u000b\u0000\u052d\u0163"+ + "\u0001\u0000\u0000\u0000\u052e\u052f\u0003>\u0017\u0000\u052f\u0530\u0001"+ + "\u0000\u0000\u0000\u0530\u0531\u0006\u00aa\u000b\u0000\u0531\u0165\u0001"+ + "\u0000\u0000\u0000\u0532\u0533\u0003\u00b4R\u0000\u0533\u0534\u0001\u0000"+ + "\u0000\u0000\u0534\u0535\u0006\u00ab\u0010\u0000\u0535\u0536\u0006\u00ab"+ + "\u000f\u0000\u0536\u0167\u0001\u0000\u0000\u0000\u0537\u0538\u0005:\u0000"+ + "\u0000\u0538\u0169\u0001\u0000\u0000\u0000\u0539\u053f\u0003Z%\u0000\u053a"+ + "\u053f\u0003P \u0000\u053b\u053f\u0003x4\u0000\u053c\u053f\u0003R!\u0000"+ + "\u053d\u053f\u0003`(\u0000\u053e\u0539\u0001\u0000\u0000\u0000\u053e\u053a"+ + "\u0001\u0000\u0000\u0000\u053e\u053b\u0001\u0000\u0000\u0000\u053e\u053c"+ + "\u0001\u0000\u0000\u0000\u053e\u053d\u0001\u0000\u0000\u0000\u053f\u0540"+ + "\u0001\u0000\u0000\u0000\u0540\u053e\u0001\u0000\u0000\u0000\u0540\u0541"+ + "\u0001\u0000\u0000\u0000\u0541\u016b\u0001\u0000\u0000\u0000\u0542\u0543"+ + "\u0003:\u0015\u0000\u0543\u0544\u0001\u0000\u0000\u0000\u0544\u0545\u0006"+ + "\u00ae\u000b\u0000\u0545\u016d\u0001\u0000\u0000\u0000\u0546\u0547\u0003"+ + "<\u0016\u0000\u0547\u0548\u0001\u0000\u0000\u0000\u0548\u0549\u0006\u00af"+ + "\u000b\u0000\u0549\u016f\u0001\u0000\u0000\u0000\u054a\u054b\u0003>\u0017"+ + "\u0000\u054b\u054c\u0001\u0000\u0000\u0000\u054c\u054d\u0006\u00b0\u000b"+ + "\u0000\u054d\u0171\u0001\u0000\u0000\u0000\u054e\u054f\u0003N\u001f\u0000"+ + "\u054f\u0550\u0001\u0000\u0000\u0000\u0550\u0551\u0006\u00b1\u000e\u0000"+ + "\u0551\u0552\u0006\u00b1\u000f\u0000\u0552\u0173\u0001\u0000\u0000\u0000"+ + "\u0553\u0554\u0003B\u0019\u0000\u0554\u0555\u0001\u0000\u0000\u0000\u0555"+ + "\u0556\u0006\u00b2\u0014\u0000\u0556\u0557\u0006\u00b2\u000f\u0000\u0557"+ + "\u0558\u0006\u00b2\u001f\u0000\u0558\u0175\u0001\u0000\u0000\u0000\u0559"+ + "\u055a\u0003:\u0015\u0000\u055a\u055b\u0001\u0000\u0000\u0000\u055b\u055c"+ + "\u0006\u00b3\u000b\u0000\u055c\u0177\u0001\u0000\u0000\u0000\u055d\u055e"+ + "\u0003<\u0016\u0000\u055e\u055f\u0001\u0000\u0000\u0000\u055f\u0560\u0006"+ + "\u00b4\u000b\u0000\u0560\u0179\u0001\u0000\u0000\u0000\u0561\u0562\u0003"+ + ">\u0017\u0000\u0562\u0563\u0001\u0000\u0000\u0000\u0563\u0564\u0006\u00b5"+ + "\u000b\u0000\u0564\u017b\u0001\u0000\u0000\u0000\u0565\u0566\u0003t2\u0000"+ + "\u0566\u0567\u0001\u0000\u0000\u0000\u0567\u0568\u0006\u00b6\u0011\u0000"+ + "\u0568\u0569\u0006\u00b6\u000f\u0000\u0569\u056a\u0006\u00b6\u0007\u0000"+ + "\u056a\u017d\u0001\u0000\u0000\u0000\u056b\u056c\u0003:\u0015\u0000\u056c"+ + "\u056d\u0001\u0000\u0000\u0000\u056d\u056e\u0006\u00b7\u000b\u0000\u056e"+ + "\u017f\u0001\u0000\u0000\u0000\u056f\u0570\u0003<\u0016\u0000\u0570\u0571"+ + "\u0001\u0000\u0000\u0000\u0571\u0572\u0006\u00b8\u000b\u0000\u0572\u0181"+ + "\u0001\u0000\u0000\u0000\u0573\u0574\u0003>\u0017\u0000\u0574\u0575\u0001"+ + "\u0000\u0000\u0000\u0575\u0576\u0006\u00b9\u000b\u0000\u0576\u0183\u0001"+ + "\u0000\u0000\u0000\u0577\u0578\u0003\u00baU\u0000\u0578\u0579\u0001\u0000"+ + "\u0000\u0000\u0579\u057a\u0006\u00ba\u000f\u0000\u057a\u057b\u0006\u00ba"+ + "\u0000\u0000\u057b\u057c\u0006\u00ba\u0019\u0000\u057c\u0185\u0001\u0000"+ + "\u0000\u0000\u057d\u057e\u0003\u00b6S\u0000\u057e\u057f\u0001\u0000\u0000"+ + "\u0000\u057f\u0580\u0006\u00bb\u000f\u0000\u0580\u0581\u0006\u00bb\u0000"+ + "\u0000\u0581\u0582\u0006\u00bb\u001e\u0000\u0582\u0187\u0001\u0000\u0000"+ + "\u0000\u0583\u0584\u0003j-\u0000\u0584\u0585\u0001\u0000\u0000\u0000\u0585"+ + "\u0586\u0006\u00bc\u000f\u0000\u0586\u0587\u0006\u00bc\u0000\u0000\u0587"+ + "\u0588\u0006\u00bc \u0000\u0588\u0189\u0001\u0000\u0000\u0000\u0589\u058a"+ + "\u0003N\u001f\u0000\u058a\u058b\u0001\u0000\u0000\u0000\u058b\u058c\u0006"+ + "\u00bd\u000e\u0000\u058c\u058d\u0006\u00bd\u000f\u0000\u058d\u018b\u0001"+ + "\u0000\u0000\u0000A\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b"+ + "\t\n\u000b\f\r\u000e\u000f\u0238\u0242\u0246\u0249\u0252\u0254\u025f\u0266"+ + "\u026b\u0292\u0297\u02a0\u02a7\u02ac\u02ae\u02b9\u02c1\u02c4\u02c6\u02cb"+ + "\u02d0\u02d6\u02dd\u02e2\u02e8\u02eb\u02f3\u02f7\u0373\u037a\u037c\u038c"+ + "\u0391\u0396\u0398\u039e\u03f3\u03f7\u03fc\u0401\u0406\u0408\u040c\u040e"+ + "\u045b\u045f\u0464\u053e\u0540!\u0005\u0002\u0000\u0005\u0004\u0000\u0005"+ + "\u0006\u0000\u0005\u0001\u0000\u0005\u0003\u0000\u0005\b\u0000\u0005\f"+ + "\u0000\u0005\u000e\u0000\u0005\n\u0000\u0005\u0005\u0000\u0005\u000b\u0000"+ + "\u0000\u0001\u0000\u0007E\u0000\u0005\u0000\u0000\u0007\u001d\u0000\u0004"+ + "\u0000\u0000\u0007F\u0000\u0007&\u0000\u0007$\u0000\u0007\u001e\u0000"+ + "\u0007\u0019\u0000\u0007(\u0000\u0007P\u0000\u0005\r\u0000\u0005\u0007"+ + "\u0000\u0007H\u0000\u0007Z\u0000\u0007Y\u0000\u0007X\u0000\u0005\t\u0000"+ + "\u0007G\u0000\u0005\u000f\u0000\u0007!\u0000"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp index 76663717c562..590002059011 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp @@ -68,6 +68,7 @@ null '/' '%' null +null ']' null null @@ -193,6 +194,7 @@ MINUS ASTERISK SLASH PERCENT +NAMED_OR_POSITIONAL_PARAM OPENING_BRACKET CLOSING_BRACKET UNQUOTED_IDENTIFIER @@ -281,6 +283,7 @@ qualifiedNamePatterns identifier identifierPattern constant +params limitCommand sortCommand orderExpression @@ -309,4 +312,4 @@ lookupCommand atn: -[4, 1, 123, 548, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 120, 8, 1, 10, 1, 12, 1, 123, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 131, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 147, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 159, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 166, 8, 5, 10, 5, 12, 5, 169, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 176, 8, 5, 1, 5, 1, 5, 3, 5, 180, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 188, 8, 5, 10, 5, 12, 5, 191, 9, 5, 1, 6, 1, 6, 3, 6, 195, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 202, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 207, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 214, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 220, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 228, 8, 8, 10, 8, 12, 8, 231, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 241, 8, 9, 1, 9, 1, 9, 1, 9, 5, 9, 246, 8, 9, 10, 9, 12, 9, 249, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 257, 8, 10, 10, 10, 12, 10, 260, 9, 10, 3, 10, 262, 8, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 5, 13, 274, 8, 13, 10, 13, 12, 13, 277, 9, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 284, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 5, 15, 290, 8, 15, 10, 15, 12, 15, 293, 9, 15, 1, 15, 3, 15, 296, 8, 15, 1, 16, 1, 16, 1, 17, 1, 17, 3, 17, 302, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 5, 18, 308, 8, 18, 10, 18, 12, 18, 311, 9, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 321, 8, 20, 10, 20, 12, 20, 324, 9, 20, 1, 20, 3, 20, 327, 8, 20, 1, 20, 1, 20, 3, 20, 331, 8, 20, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 3, 22, 338, 8, 22, 1, 22, 1, 22, 3, 22, 342, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 348, 8, 23, 1, 24, 1, 24, 1, 24, 5, 24, 353, 8, 24, 10, 24, 12, 24, 356, 9, 24, 1, 25, 1, 25, 1, 25, 5, 25, 361, 8, 25, 10, 25, 12, 25, 364, 9, 25, 1, 26, 1, 26, 1, 26, 5, 26, 369, 8, 26, 10, 26, 12, 26, 372, 9, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 391, 8, 29, 10, 29, 12, 29, 394, 9, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 402, 8, 29, 10, 29, 12, 29, 405, 9, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 413, 8, 29, 10, 29, 12, 29, 416, 9, 29, 1, 29, 1, 29, 3, 29, 420, 8, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 429, 8, 31, 10, 31, 12, 31, 432, 9, 31, 1, 32, 1, 32, 3, 32, 436, 8, 32, 1, 32, 1, 32, 3, 32, 440, 8, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 452, 8, 35, 10, 35, 12, 35, 455, 9, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 465, 8, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 5, 40, 477, 8, 40, 10, 40, 12, 40, 480, 9, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 3, 43, 490, 8, 43, 1, 44, 3, 44, 493, 8, 44, 1, 44, 1, 44, 1, 45, 3, 45, 498, 8, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 523, 8, 52, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 529, 8, 52, 10, 52, 12, 52, 532, 9, 52, 3, 52, 534, 8, 52, 1, 53, 1, 53, 1, 53, 3, 53, 539, 8, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 0, 4, 2, 10, 16, 18, 55, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 0, 7, 1, 0, 63, 64, 1, 0, 65, 67, 1, 0, 70, 71, 2, 0, 35, 35, 39, 39, 1, 0, 42, 43, 2, 0, 41, 41, 55, 55, 2, 0, 56, 56, 58, 62, 574, 0, 110, 1, 0, 0, 0, 2, 113, 1, 0, 0, 0, 4, 130, 1, 0, 0, 0, 6, 146, 1, 0, 0, 0, 8, 148, 1, 0, 0, 0, 10, 179, 1, 0, 0, 0, 12, 206, 1, 0, 0, 0, 14, 213, 1, 0, 0, 0, 16, 219, 1, 0, 0, 0, 18, 240, 1, 0, 0, 0, 20, 250, 1, 0, 0, 0, 22, 265, 1, 0, 0, 0, 24, 267, 1, 0, 0, 0, 26, 270, 1, 0, 0, 0, 28, 283, 1, 0, 0, 0, 30, 285, 1, 0, 0, 0, 32, 297, 1, 0, 0, 0, 34, 301, 1, 0, 0, 0, 36, 303, 1, 0, 0, 0, 38, 312, 1, 0, 0, 0, 40, 316, 1, 0, 0, 0, 42, 332, 1, 0, 0, 0, 44, 335, 1, 0, 0, 0, 46, 343, 1, 0, 0, 0, 48, 349, 1, 0, 0, 0, 50, 357, 1, 0, 0, 0, 52, 365, 1, 0, 0, 0, 54, 373, 1, 0, 0, 0, 56, 375, 1, 0, 0, 0, 58, 419, 1, 0, 0, 0, 60, 421, 1, 0, 0, 0, 62, 424, 1, 0, 0, 0, 64, 433, 1, 0, 0, 0, 66, 441, 1, 0, 0, 0, 68, 444, 1, 0, 0, 0, 70, 447, 1, 0, 0, 0, 72, 456, 1, 0, 0, 0, 74, 460, 1, 0, 0, 0, 76, 466, 1, 0, 0, 0, 78, 470, 1, 0, 0, 0, 80, 473, 1, 0, 0, 0, 82, 481, 1, 0, 0, 0, 84, 485, 1, 0, 0, 0, 86, 489, 1, 0, 0, 0, 88, 492, 1, 0, 0, 0, 90, 497, 1, 0, 0, 0, 92, 501, 1, 0, 0, 0, 94, 503, 1, 0, 0, 0, 96, 505, 1, 0, 0, 0, 98, 508, 1, 0, 0, 0, 100, 512, 1, 0, 0, 0, 102, 515, 1, 0, 0, 0, 104, 518, 1, 0, 0, 0, 106, 538, 1, 0, 0, 0, 108, 542, 1, 0, 0, 0, 110, 111, 3, 2, 1, 0, 111, 112, 5, 0, 0, 1, 112, 1, 1, 0, 0, 0, 113, 114, 6, 1, -1, 0, 114, 115, 3, 4, 2, 0, 115, 121, 1, 0, 0, 0, 116, 117, 10, 1, 0, 0, 117, 118, 5, 29, 0, 0, 118, 120, 3, 6, 3, 0, 119, 116, 1, 0, 0, 0, 120, 123, 1, 0, 0, 0, 121, 119, 1, 0, 0, 0, 121, 122, 1, 0, 0, 0, 122, 3, 1, 0, 0, 0, 123, 121, 1, 0, 0, 0, 124, 131, 3, 96, 48, 0, 125, 131, 3, 30, 15, 0, 126, 131, 3, 24, 12, 0, 127, 131, 3, 40, 20, 0, 128, 131, 3, 100, 50, 0, 129, 131, 3, 102, 51, 0, 130, 124, 1, 0, 0, 0, 130, 125, 1, 0, 0, 0, 130, 126, 1, 0, 0, 0, 130, 127, 1, 0, 0, 0, 130, 128, 1, 0, 0, 0, 130, 129, 1, 0, 0, 0, 131, 5, 1, 0, 0, 0, 132, 147, 3, 42, 21, 0, 133, 147, 3, 46, 23, 0, 134, 147, 3, 60, 30, 0, 135, 147, 3, 108, 54, 0, 136, 147, 3, 66, 33, 0, 137, 147, 3, 62, 31, 0, 138, 147, 3, 44, 22, 0, 139, 147, 3, 8, 4, 0, 140, 147, 3, 68, 34, 0, 141, 147, 3, 70, 35, 0, 142, 147, 3, 74, 37, 0, 143, 147, 3, 76, 38, 0, 144, 147, 3, 104, 52, 0, 145, 147, 3, 78, 39, 0, 146, 132, 1, 0, 0, 0, 146, 133, 1, 0, 0, 0, 146, 134, 1, 0, 0, 0, 146, 135, 1, 0, 0, 0, 146, 136, 1, 0, 0, 0, 146, 137, 1, 0, 0, 0, 146, 138, 1, 0, 0, 0, 146, 139, 1, 0, 0, 0, 146, 140, 1, 0, 0, 0, 146, 141, 1, 0, 0, 0, 146, 142, 1, 0, 0, 0, 146, 143, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 146, 145, 1, 0, 0, 0, 147, 7, 1, 0, 0, 0, 148, 149, 5, 20, 0, 0, 149, 150, 3, 10, 5, 0, 150, 9, 1, 0, 0, 0, 151, 152, 6, 5, -1, 0, 152, 153, 5, 48, 0, 0, 153, 180, 3, 10, 5, 7, 154, 180, 3, 14, 7, 0, 155, 180, 3, 12, 6, 0, 156, 158, 3, 14, 7, 0, 157, 159, 5, 48, 0, 0, 158, 157, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 160, 1, 0, 0, 0, 160, 161, 5, 45, 0, 0, 161, 162, 5, 44, 0, 0, 162, 167, 3, 14, 7, 0, 163, 164, 5, 38, 0, 0, 164, 166, 3, 14, 7, 0, 165, 163, 1, 0, 0, 0, 166, 169, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 170, 1, 0, 0, 0, 169, 167, 1, 0, 0, 0, 170, 171, 5, 54, 0, 0, 171, 180, 1, 0, 0, 0, 172, 173, 3, 14, 7, 0, 173, 175, 5, 46, 0, 0, 174, 176, 5, 48, 0, 0, 175, 174, 1, 0, 0, 0, 175, 176, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 178, 5, 49, 0, 0, 178, 180, 1, 0, 0, 0, 179, 151, 1, 0, 0, 0, 179, 154, 1, 0, 0, 0, 179, 155, 1, 0, 0, 0, 179, 156, 1, 0, 0, 0, 179, 172, 1, 0, 0, 0, 180, 189, 1, 0, 0, 0, 181, 182, 10, 4, 0, 0, 182, 183, 5, 34, 0, 0, 183, 188, 3, 10, 5, 5, 184, 185, 10, 3, 0, 0, 185, 186, 5, 51, 0, 0, 186, 188, 3, 10, 5, 4, 187, 181, 1, 0, 0, 0, 187, 184, 1, 0, 0, 0, 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 11, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 194, 3, 14, 7, 0, 193, 195, 5, 48, 0, 0, 194, 193, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 197, 5, 47, 0, 0, 197, 198, 3, 92, 46, 0, 198, 207, 1, 0, 0, 0, 199, 201, 3, 14, 7, 0, 200, 202, 5, 48, 0, 0, 201, 200, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 204, 5, 53, 0, 0, 204, 205, 3, 92, 46, 0, 205, 207, 1, 0, 0, 0, 206, 192, 1, 0, 0, 0, 206, 199, 1, 0, 0, 0, 207, 13, 1, 0, 0, 0, 208, 214, 3, 16, 8, 0, 209, 210, 3, 16, 8, 0, 210, 211, 3, 94, 47, 0, 211, 212, 3, 16, 8, 0, 212, 214, 1, 0, 0, 0, 213, 208, 1, 0, 0, 0, 213, 209, 1, 0, 0, 0, 214, 15, 1, 0, 0, 0, 215, 216, 6, 8, -1, 0, 216, 220, 3, 18, 9, 0, 217, 218, 7, 0, 0, 0, 218, 220, 3, 16, 8, 3, 219, 215, 1, 0, 0, 0, 219, 217, 1, 0, 0, 0, 220, 229, 1, 0, 0, 0, 221, 222, 10, 2, 0, 0, 222, 223, 7, 1, 0, 0, 223, 228, 3, 16, 8, 3, 224, 225, 10, 1, 0, 0, 225, 226, 7, 0, 0, 0, 226, 228, 3, 16, 8, 2, 227, 221, 1, 0, 0, 0, 227, 224, 1, 0, 0, 0, 228, 231, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 230, 17, 1, 0, 0, 0, 231, 229, 1, 0, 0, 0, 232, 233, 6, 9, -1, 0, 233, 241, 3, 58, 29, 0, 234, 241, 3, 48, 24, 0, 235, 241, 3, 20, 10, 0, 236, 237, 5, 44, 0, 0, 237, 238, 3, 10, 5, 0, 238, 239, 5, 54, 0, 0, 239, 241, 1, 0, 0, 0, 240, 232, 1, 0, 0, 0, 240, 234, 1, 0, 0, 0, 240, 235, 1, 0, 0, 0, 240, 236, 1, 0, 0, 0, 241, 247, 1, 0, 0, 0, 242, 243, 10, 1, 0, 0, 243, 244, 5, 37, 0, 0, 244, 246, 3, 22, 11, 0, 245, 242, 1, 0, 0, 0, 246, 249, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 19, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 250, 251, 3, 54, 27, 0, 251, 261, 5, 44, 0, 0, 252, 262, 5, 65, 0, 0, 253, 258, 3, 10, 5, 0, 254, 255, 5, 38, 0, 0, 255, 257, 3, 10, 5, 0, 256, 254, 1, 0, 0, 0, 257, 260, 1, 0, 0, 0, 258, 256, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 262, 1, 0, 0, 0, 260, 258, 1, 0, 0, 0, 261, 252, 1, 0, 0, 0, 261, 253, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 264, 5, 54, 0, 0, 264, 21, 1, 0, 0, 0, 265, 266, 3, 54, 27, 0, 266, 23, 1, 0, 0, 0, 267, 268, 5, 16, 0, 0, 268, 269, 3, 26, 13, 0, 269, 25, 1, 0, 0, 0, 270, 275, 3, 28, 14, 0, 271, 272, 5, 38, 0, 0, 272, 274, 3, 28, 14, 0, 273, 271, 1, 0, 0, 0, 274, 277, 1, 0, 0, 0, 275, 273, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, 276, 27, 1, 0, 0, 0, 277, 275, 1, 0, 0, 0, 278, 284, 3, 10, 5, 0, 279, 280, 3, 48, 24, 0, 280, 281, 5, 36, 0, 0, 281, 282, 3, 10, 5, 0, 282, 284, 1, 0, 0, 0, 283, 278, 1, 0, 0, 0, 283, 279, 1, 0, 0, 0, 284, 29, 1, 0, 0, 0, 285, 286, 5, 6, 0, 0, 286, 291, 3, 32, 16, 0, 287, 288, 5, 38, 0, 0, 288, 290, 3, 32, 16, 0, 289, 287, 1, 0, 0, 0, 290, 293, 1, 0, 0, 0, 291, 289, 1, 0, 0, 0, 291, 292, 1, 0, 0, 0, 292, 295, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 294, 296, 3, 34, 17, 0, 295, 294, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 31, 1, 0, 0, 0, 297, 298, 5, 25, 0, 0, 298, 33, 1, 0, 0, 0, 299, 302, 3, 36, 18, 0, 300, 302, 3, 38, 19, 0, 301, 299, 1, 0, 0, 0, 301, 300, 1, 0, 0, 0, 302, 35, 1, 0, 0, 0, 303, 304, 5, 75, 0, 0, 304, 309, 3, 32, 16, 0, 305, 306, 5, 38, 0, 0, 306, 308, 3, 32, 16, 0, 307, 305, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 309, 310, 1, 0, 0, 0, 310, 37, 1, 0, 0, 0, 311, 309, 1, 0, 0, 0, 312, 313, 5, 68, 0, 0, 313, 314, 3, 36, 18, 0, 314, 315, 5, 69, 0, 0, 315, 39, 1, 0, 0, 0, 316, 317, 5, 13, 0, 0, 317, 322, 3, 32, 16, 0, 318, 319, 5, 38, 0, 0, 319, 321, 3, 32, 16, 0, 320, 318, 1, 0, 0, 0, 321, 324, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 322, 323, 1, 0, 0, 0, 323, 326, 1, 0, 0, 0, 324, 322, 1, 0, 0, 0, 325, 327, 3, 26, 13, 0, 326, 325, 1, 0, 0, 0, 326, 327, 1, 0, 0, 0, 327, 330, 1, 0, 0, 0, 328, 329, 5, 33, 0, 0, 329, 331, 3, 26, 13, 0, 330, 328, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 41, 1, 0, 0, 0, 332, 333, 5, 4, 0, 0, 333, 334, 3, 26, 13, 0, 334, 43, 1, 0, 0, 0, 335, 337, 5, 19, 0, 0, 336, 338, 3, 26, 13, 0, 337, 336, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 340, 5, 33, 0, 0, 340, 342, 3, 26, 13, 0, 341, 339, 1, 0, 0, 0, 341, 342, 1, 0, 0, 0, 342, 45, 1, 0, 0, 0, 343, 344, 5, 8, 0, 0, 344, 347, 3, 26, 13, 0, 345, 346, 5, 33, 0, 0, 346, 348, 3, 26, 13, 0, 347, 345, 1, 0, 0, 0, 347, 348, 1, 0, 0, 0, 348, 47, 1, 0, 0, 0, 349, 354, 3, 54, 27, 0, 350, 351, 5, 40, 0, 0, 351, 353, 3, 54, 27, 0, 352, 350, 1, 0, 0, 0, 353, 356, 1, 0, 0, 0, 354, 352, 1, 0, 0, 0, 354, 355, 1, 0, 0, 0, 355, 49, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 357, 362, 3, 56, 28, 0, 358, 359, 5, 40, 0, 0, 359, 361, 3, 56, 28, 0, 360, 358, 1, 0, 0, 0, 361, 364, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 51, 1, 0, 0, 0, 364, 362, 1, 0, 0, 0, 365, 370, 3, 50, 25, 0, 366, 367, 5, 38, 0, 0, 367, 369, 3, 50, 25, 0, 368, 366, 1, 0, 0, 0, 369, 372, 1, 0, 0, 0, 370, 368, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 53, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 373, 374, 7, 2, 0, 0, 374, 55, 1, 0, 0, 0, 375, 376, 5, 79, 0, 0, 376, 57, 1, 0, 0, 0, 377, 420, 5, 49, 0, 0, 378, 379, 3, 90, 45, 0, 379, 380, 5, 70, 0, 0, 380, 420, 1, 0, 0, 0, 381, 420, 3, 88, 44, 0, 382, 420, 3, 90, 45, 0, 383, 420, 3, 84, 42, 0, 384, 420, 5, 52, 0, 0, 385, 420, 3, 92, 46, 0, 386, 387, 5, 68, 0, 0, 387, 392, 3, 86, 43, 0, 388, 389, 5, 38, 0, 0, 389, 391, 3, 86, 43, 0, 390, 388, 1, 0, 0, 0, 391, 394, 1, 0, 0, 0, 392, 390, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 395, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, 395, 396, 5, 69, 0, 0, 396, 420, 1, 0, 0, 0, 397, 398, 5, 68, 0, 0, 398, 403, 3, 84, 42, 0, 399, 400, 5, 38, 0, 0, 400, 402, 3, 84, 42, 0, 401, 399, 1, 0, 0, 0, 402, 405, 1, 0, 0, 0, 403, 401, 1, 0, 0, 0, 403, 404, 1, 0, 0, 0, 404, 406, 1, 0, 0, 0, 405, 403, 1, 0, 0, 0, 406, 407, 5, 69, 0, 0, 407, 420, 1, 0, 0, 0, 408, 409, 5, 68, 0, 0, 409, 414, 3, 92, 46, 0, 410, 411, 5, 38, 0, 0, 411, 413, 3, 92, 46, 0, 412, 410, 1, 0, 0, 0, 413, 416, 1, 0, 0, 0, 414, 412, 1, 0, 0, 0, 414, 415, 1, 0, 0, 0, 415, 417, 1, 0, 0, 0, 416, 414, 1, 0, 0, 0, 417, 418, 5, 69, 0, 0, 418, 420, 1, 0, 0, 0, 419, 377, 1, 0, 0, 0, 419, 378, 1, 0, 0, 0, 419, 381, 1, 0, 0, 0, 419, 382, 1, 0, 0, 0, 419, 383, 1, 0, 0, 0, 419, 384, 1, 0, 0, 0, 419, 385, 1, 0, 0, 0, 419, 386, 1, 0, 0, 0, 419, 397, 1, 0, 0, 0, 419, 408, 1, 0, 0, 0, 420, 59, 1, 0, 0, 0, 421, 422, 5, 10, 0, 0, 422, 423, 5, 31, 0, 0, 423, 61, 1, 0, 0, 0, 424, 425, 5, 18, 0, 0, 425, 430, 3, 64, 32, 0, 426, 427, 5, 38, 0, 0, 427, 429, 3, 64, 32, 0, 428, 426, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 63, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 433, 435, 3, 10, 5, 0, 434, 436, 7, 3, 0, 0, 435, 434, 1, 0, 0, 0, 435, 436, 1, 0, 0, 0, 436, 439, 1, 0, 0, 0, 437, 438, 5, 50, 0, 0, 438, 440, 7, 4, 0, 0, 439, 437, 1, 0, 0, 0, 439, 440, 1, 0, 0, 0, 440, 65, 1, 0, 0, 0, 441, 442, 5, 9, 0, 0, 442, 443, 3, 52, 26, 0, 443, 67, 1, 0, 0, 0, 444, 445, 5, 2, 0, 0, 445, 446, 3, 52, 26, 0, 446, 69, 1, 0, 0, 0, 447, 448, 5, 15, 0, 0, 448, 453, 3, 72, 36, 0, 449, 450, 5, 38, 0, 0, 450, 452, 3, 72, 36, 0, 451, 449, 1, 0, 0, 0, 452, 455, 1, 0, 0, 0, 453, 451, 1, 0, 0, 0, 453, 454, 1, 0, 0, 0, 454, 71, 1, 0, 0, 0, 455, 453, 1, 0, 0, 0, 456, 457, 3, 50, 25, 0, 457, 458, 5, 83, 0, 0, 458, 459, 3, 50, 25, 0, 459, 73, 1, 0, 0, 0, 460, 461, 5, 1, 0, 0, 461, 462, 3, 18, 9, 0, 462, 464, 3, 92, 46, 0, 463, 465, 3, 80, 40, 0, 464, 463, 1, 0, 0, 0, 464, 465, 1, 0, 0, 0, 465, 75, 1, 0, 0, 0, 466, 467, 5, 7, 0, 0, 467, 468, 3, 18, 9, 0, 468, 469, 3, 92, 46, 0, 469, 77, 1, 0, 0, 0, 470, 471, 5, 14, 0, 0, 471, 472, 3, 48, 24, 0, 472, 79, 1, 0, 0, 0, 473, 478, 3, 82, 41, 0, 474, 475, 5, 38, 0, 0, 475, 477, 3, 82, 41, 0, 476, 474, 1, 0, 0, 0, 477, 480, 1, 0, 0, 0, 478, 476, 1, 0, 0, 0, 478, 479, 1, 0, 0, 0, 479, 81, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 481, 482, 3, 54, 27, 0, 482, 483, 5, 36, 0, 0, 483, 484, 3, 58, 29, 0, 484, 83, 1, 0, 0, 0, 485, 486, 7, 5, 0, 0, 486, 85, 1, 0, 0, 0, 487, 490, 3, 88, 44, 0, 488, 490, 3, 90, 45, 0, 489, 487, 1, 0, 0, 0, 489, 488, 1, 0, 0, 0, 490, 87, 1, 0, 0, 0, 491, 493, 7, 0, 0, 0, 492, 491, 1, 0, 0, 0, 492, 493, 1, 0, 0, 0, 493, 494, 1, 0, 0, 0, 494, 495, 5, 32, 0, 0, 495, 89, 1, 0, 0, 0, 496, 498, 7, 0, 0, 0, 497, 496, 1, 0, 0, 0, 497, 498, 1, 0, 0, 0, 498, 499, 1, 0, 0, 0, 499, 500, 5, 31, 0, 0, 500, 91, 1, 0, 0, 0, 501, 502, 5, 30, 0, 0, 502, 93, 1, 0, 0, 0, 503, 504, 7, 6, 0, 0, 504, 95, 1, 0, 0, 0, 505, 506, 5, 5, 0, 0, 506, 507, 3, 98, 49, 0, 507, 97, 1, 0, 0, 0, 508, 509, 5, 68, 0, 0, 509, 510, 3, 2, 1, 0, 510, 511, 5, 69, 0, 0, 511, 99, 1, 0, 0, 0, 512, 513, 5, 17, 0, 0, 513, 514, 5, 105, 0, 0, 514, 101, 1, 0, 0, 0, 515, 516, 5, 12, 0, 0, 516, 517, 5, 109, 0, 0, 517, 103, 1, 0, 0, 0, 518, 519, 5, 3, 0, 0, 519, 522, 5, 89, 0, 0, 520, 521, 5, 87, 0, 0, 521, 523, 3, 50, 25, 0, 522, 520, 1, 0, 0, 0, 522, 523, 1, 0, 0, 0, 523, 533, 1, 0, 0, 0, 524, 525, 5, 88, 0, 0, 525, 530, 3, 106, 53, 0, 526, 527, 5, 38, 0, 0, 527, 529, 3, 106, 53, 0, 528, 526, 1, 0, 0, 0, 529, 532, 1, 0, 0, 0, 530, 528, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 534, 1, 0, 0, 0, 532, 530, 1, 0, 0, 0, 533, 524, 1, 0, 0, 0, 533, 534, 1, 0, 0, 0, 534, 105, 1, 0, 0, 0, 535, 536, 3, 50, 25, 0, 536, 537, 5, 36, 0, 0, 537, 539, 1, 0, 0, 0, 538, 535, 1, 0, 0, 0, 538, 539, 1, 0, 0, 0, 539, 540, 1, 0, 0, 0, 540, 541, 3, 50, 25, 0, 541, 107, 1, 0, 0, 0, 542, 543, 5, 11, 0, 0, 543, 544, 5, 25, 0, 0, 544, 545, 5, 87, 0, 0, 545, 546, 3, 52, 26, 0, 546, 109, 1, 0, 0, 0, 52, 121, 130, 146, 158, 167, 175, 179, 187, 189, 194, 201, 206, 213, 219, 227, 229, 240, 247, 258, 261, 275, 283, 291, 295, 301, 309, 322, 326, 330, 337, 341, 347, 354, 362, 370, 392, 403, 414, 419, 430, 435, 439, 453, 464, 478, 489, 492, 497, 522, 530, 533, 538] \ No newline at end of file +[4, 1, 124, 554, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 122, 8, 1, 10, 1, 12, 1, 125, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 133, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 149, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 161, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 168, 8, 5, 10, 5, 12, 5, 171, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 178, 8, 5, 1, 5, 1, 5, 3, 5, 182, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 190, 8, 5, 10, 5, 12, 5, 193, 9, 5, 1, 6, 1, 6, 3, 6, 197, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 204, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 209, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 216, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 222, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 230, 8, 8, 10, 8, 12, 8, 233, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 243, 8, 9, 1, 9, 1, 9, 1, 9, 5, 9, 248, 8, 9, 10, 9, 12, 9, 251, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 259, 8, 10, 10, 10, 12, 10, 262, 9, 10, 3, 10, 264, 8, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 5, 13, 276, 8, 13, 10, 13, 12, 13, 279, 9, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 286, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 5, 15, 292, 8, 15, 10, 15, 12, 15, 295, 9, 15, 1, 15, 3, 15, 298, 8, 15, 1, 16, 1, 16, 1, 17, 1, 17, 3, 17, 304, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 5, 18, 310, 8, 18, 10, 18, 12, 18, 313, 9, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 323, 8, 20, 10, 20, 12, 20, 326, 9, 20, 1, 20, 3, 20, 329, 8, 20, 1, 20, 1, 20, 3, 20, 333, 8, 20, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 3, 22, 340, 8, 22, 1, 22, 1, 22, 3, 22, 344, 8, 22, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 350, 8, 23, 1, 24, 1, 24, 1, 24, 5, 24, 355, 8, 24, 10, 24, 12, 24, 358, 9, 24, 1, 25, 1, 25, 1, 25, 5, 25, 363, 8, 25, 10, 25, 12, 25, 366, 9, 25, 1, 26, 1, 26, 1, 26, 5, 26, 371, 8, 26, 10, 26, 12, 26, 374, 9, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 393, 8, 29, 10, 29, 12, 29, 396, 9, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 404, 8, 29, 10, 29, 12, 29, 407, 9, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 415, 8, 29, 10, 29, 12, 29, 418, 9, 29, 1, 29, 1, 29, 3, 29, 422, 8, 29, 1, 30, 1, 30, 3, 30, 426, 8, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 435, 8, 32, 10, 32, 12, 32, 438, 9, 32, 1, 33, 1, 33, 3, 33, 442, 8, 33, 1, 33, 1, 33, 3, 33, 446, 8, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 458, 8, 36, 10, 36, 12, 36, 461, 9, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 471, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 5, 41, 483, 8, 41, 10, 41, 12, 41, 486, 9, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 3, 44, 496, 8, 44, 1, 45, 3, 45, 499, 8, 45, 1, 45, 1, 45, 1, 46, 3, 46, 504, 8, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 529, 8, 53, 1, 53, 1, 53, 1, 53, 1, 53, 5, 53, 535, 8, 53, 10, 53, 12, 53, 538, 9, 53, 3, 53, 540, 8, 53, 1, 54, 1, 54, 1, 54, 3, 54, 545, 8, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 0, 4, 2, 10, 16, 18, 56, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 0, 7, 1, 0, 63, 64, 1, 0, 65, 67, 1, 0, 71, 72, 2, 0, 35, 35, 39, 39, 1, 0, 42, 43, 2, 0, 41, 41, 55, 55, 2, 0, 56, 56, 58, 62, 580, 0, 112, 1, 0, 0, 0, 2, 115, 1, 0, 0, 0, 4, 132, 1, 0, 0, 0, 6, 148, 1, 0, 0, 0, 8, 150, 1, 0, 0, 0, 10, 181, 1, 0, 0, 0, 12, 208, 1, 0, 0, 0, 14, 215, 1, 0, 0, 0, 16, 221, 1, 0, 0, 0, 18, 242, 1, 0, 0, 0, 20, 252, 1, 0, 0, 0, 22, 267, 1, 0, 0, 0, 24, 269, 1, 0, 0, 0, 26, 272, 1, 0, 0, 0, 28, 285, 1, 0, 0, 0, 30, 287, 1, 0, 0, 0, 32, 299, 1, 0, 0, 0, 34, 303, 1, 0, 0, 0, 36, 305, 1, 0, 0, 0, 38, 314, 1, 0, 0, 0, 40, 318, 1, 0, 0, 0, 42, 334, 1, 0, 0, 0, 44, 337, 1, 0, 0, 0, 46, 345, 1, 0, 0, 0, 48, 351, 1, 0, 0, 0, 50, 359, 1, 0, 0, 0, 52, 367, 1, 0, 0, 0, 54, 375, 1, 0, 0, 0, 56, 377, 1, 0, 0, 0, 58, 421, 1, 0, 0, 0, 60, 425, 1, 0, 0, 0, 62, 427, 1, 0, 0, 0, 64, 430, 1, 0, 0, 0, 66, 439, 1, 0, 0, 0, 68, 447, 1, 0, 0, 0, 70, 450, 1, 0, 0, 0, 72, 453, 1, 0, 0, 0, 74, 462, 1, 0, 0, 0, 76, 466, 1, 0, 0, 0, 78, 472, 1, 0, 0, 0, 80, 476, 1, 0, 0, 0, 82, 479, 1, 0, 0, 0, 84, 487, 1, 0, 0, 0, 86, 491, 1, 0, 0, 0, 88, 495, 1, 0, 0, 0, 90, 498, 1, 0, 0, 0, 92, 503, 1, 0, 0, 0, 94, 507, 1, 0, 0, 0, 96, 509, 1, 0, 0, 0, 98, 511, 1, 0, 0, 0, 100, 514, 1, 0, 0, 0, 102, 518, 1, 0, 0, 0, 104, 521, 1, 0, 0, 0, 106, 524, 1, 0, 0, 0, 108, 544, 1, 0, 0, 0, 110, 548, 1, 0, 0, 0, 112, 113, 3, 2, 1, 0, 113, 114, 5, 0, 0, 1, 114, 1, 1, 0, 0, 0, 115, 116, 6, 1, -1, 0, 116, 117, 3, 4, 2, 0, 117, 123, 1, 0, 0, 0, 118, 119, 10, 1, 0, 0, 119, 120, 5, 29, 0, 0, 120, 122, 3, 6, 3, 0, 121, 118, 1, 0, 0, 0, 122, 125, 1, 0, 0, 0, 123, 121, 1, 0, 0, 0, 123, 124, 1, 0, 0, 0, 124, 3, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 126, 133, 3, 98, 49, 0, 127, 133, 3, 30, 15, 0, 128, 133, 3, 24, 12, 0, 129, 133, 3, 40, 20, 0, 130, 133, 3, 102, 51, 0, 131, 133, 3, 104, 52, 0, 132, 126, 1, 0, 0, 0, 132, 127, 1, 0, 0, 0, 132, 128, 1, 0, 0, 0, 132, 129, 1, 0, 0, 0, 132, 130, 1, 0, 0, 0, 132, 131, 1, 0, 0, 0, 133, 5, 1, 0, 0, 0, 134, 149, 3, 42, 21, 0, 135, 149, 3, 46, 23, 0, 136, 149, 3, 62, 31, 0, 137, 149, 3, 110, 55, 0, 138, 149, 3, 68, 34, 0, 139, 149, 3, 64, 32, 0, 140, 149, 3, 44, 22, 0, 141, 149, 3, 8, 4, 0, 142, 149, 3, 70, 35, 0, 143, 149, 3, 72, 36, 0, 144, 149, 3, 76, 38, 0, 145, 149, 3, 78, 39, 0, 146, 149, 3, 106, 53, 0, 147, 149, 3, 80, 40, 0, 148, 134, 1, 0, 0, 0, 148, 135, 1, 0, 0, 0, 148, 136, 1, 0, 0, 0, 148, 137, 1, 0, 0, 0, 148, 138, 1, 0, 0, 0, 148, 139, 1, 0, 0, 0, 148, 140, 1, 0, 0, 0, 148, 141, 1, 0, 0, 0, 148, 142, 1, 0, 0, 0, 148, 143, 1, 0, 0, 0, 148, 144, 1, 0, 0, 0, 148, 145, 1, 0, 0, 0, 148, 146, 1, 0, 0, 0, 148, 147, 1, 0, 0, 0, 149, 7, 1, 0, 0, 0, 150, 151, 5, 20, 0, 0, 151, 152, 3, 10, 5, 0, 152, 9, 1, 0, 0, 0, 153, 154, 6, 5, -1, 0, 154, 155, 5, 48, 0, 0, 155, 182, 3, 10, 5, 7, 156, 182, 3, 14, 7, 0, 157, 182, 3, 12, 6, 0, 158, 160, 3, 14, 7, 0, 159, 161, 5, 48, 0, 0, 160, 159, 1, 0, 0, 0, 160, 161, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 163, 5, 45, 0, 0, 163, 164, 5, 44, 0, 0, 164, 169, 3, 14, 7, 0, 165, 166, 5, 38, 0, 0, 166, 168, 3, 14, 7, 0, 167, 165, 1, 0, 0, 0, 168, 171, 1, 0, 0, 0, 169, 167, 1, 0, 0, 0, 169, 170, 1, 0, 0, 0, 170, 172, 1, 0, 0, 0, 171, 169, 1, 0, 0, 0, 172, 173, 5, 54, 0, 0, 173, 182, 1, 0, 0, 0, 174, 175, 3, 14, 7, 0, 175, 177, 5, 46, 0, 0, 176, 178, 5, 48, 0, 0, 177, 176, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 179, 1, 0, 0, 0, 179, 180, 5, 49, 0, 0, 180, 182, 1, 0, 0, 0, 181, 153, 1, 0, 0, 0, 181, 156, 1, 0, 0, 0, 181, 157, 1, 0, 0, 0, 181, 158, 1, 0, 0, 0, 181, 174, 1, 0, 0, 0, 182, 191, 1, 0, 0, 0, 183, 184, 10, 4, 0, 0, 184, 185, 5, 34, 0, 0, 185, 190, 3, 10, 5, 5, 186, 187, 10, 3, 0, 0, 187, 188, 5, 51, 0, 0, 188, 190, 3, 10, 5, 4, 189, 183, 1, 0, 0, 0, 189, 186, 1, 0, 0, 0, 190, 193, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 191, 192, 1, 0, 0, 0, 192, 11, 1, 0, 0, 0, 193, 191, 1, 0, 0, 0, 194, 196, 3, 14, 7, 0, 195, 197, 5, 48, 0, 0, 196, 195, 1, 0, 0, 0, 196, 197, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, 5, 47, 0, 0, 199, 200, 3, 94, 47, 0, 200, 209, 1, 0, 0, 0, 201, 203, 3, 14, 7, 0, 202, 204, 5, 48, 0, 0, 203, 202, 1, 0, 0, 0, 203, 204, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 206, 5, 53, 0, 0, 206, 207, 3, 94, 47, 0, 207, 209, 1, 0, 0, 0, 208, 194, 1, 0, 0, 0, 208, 201, 1, 0, 0, 0, 209, 13, 1, 0, 0, 0, 210, 216, 3, 16, 8, 0, 211, 212, 3, 16, 8, 0, 212, 213, 3, 96, 48, 0, 213, 214, 3, 16, 8, 0, 214, 216, 1, 0, 0, 0, 215, 210, 1, 0, 0, 0, 215, 211, 1, 0, 0, 0, 216, 15, 1, 0, 0, 0, 217, 218, 6, 8, -1, 0, 218, 222, 3, 18, 9, 0, 219, 220, 7, 0, 0, 0, 220, 222, 3, 16, 8, 3, 221, 217, 1, 0, 0, 0, 221, 219, 1, 0, 0, 0, 222, 231, 1, 0, 0, 0, 223, 224, 10, 2, 0, 0, 224, 225, 7, 1, 0, 0, 225, 230, 3, 16, 8, 3, 226, 227, 10, 1, 0, 0, 227, 228, 7, 0, 0, 0, 228, 230, 3, 16, 8, 2, 229, 223, 1, 0, 0, 0, 229, 226, 1, 0, 0, 0, 230, 233, 1, 0, 0, 0, 231, 229, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 17, 1, 0, 0, 0, 233, 231, 1, 0, 0, 0, 234, 235, 6, 9, -1, 0, 235, 243, 3, 58, 29, 0, 236, 243, 3, 48, 24, 0, 237, 243, 3, 20, 10, 0, 238, 239, 5, 44, 0, 0, 239, 240, 3, 10, 5, 0, 240, 241, 5, 54, 0, 0, 241, 243, 1, 0, 0, 0, 242, 234, 1, 0, 0, 0, 242, 236, 1, 0, 0, 0, 242, 237, 1, 0, 0, 0, 242, 238, 1, 0, 0, 0, 243, 249, 1, 0, 0, 0, 244, 245, 10, 1, 0, 0, 245, 246, 5, 37, 0, 0, 246, 248, 3, 22, 11, 0, 247, 244, 1, 0, 0, 0, 248, 251, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 249, 250, 1, 0, 0, 0, 250, 19, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 252, 253, 3, 54, 27, 0, 253, 263, 5, 44, 0, 0, 254, 264, 5, 65, 0, 0, 255, 260, 3, 10, 5, 0, 256, 257, 5, 38, 0, 0, 257, 259, 3, 10, 5, 0, 258, 256, 1, 0, 0, 0, 259, 262, 1, 0, 0, 0, 260, 258, 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 264, 1, 0, 0, 0, 262, 260, 1, 0, 0, 0, 263, 254, 1, 0, 0, 0, 263, 255, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 266, 5, 54, 0, 0, 266, 21, 1, 0, 0, 0, 267, 268, 3, 54, 27, 0, 268, 23, 1, 0, 0, 0, 269, 270, 5, 16, 0, 0, 270, 271, 3, 26, 13, 0, 271, 25, 1, 0, 0, 0, 272, 277, 3, 28, 14, 0, 273, 274, 5, 38, 0, 0, 274, 276, 3, 28, 14, 0, 275, 273, 1, 0, 0, 0, 276, 279, 1, 0, 0, 0, 277, 275, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 27, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 280, 286, 3, 10, 5, 0, 281, 282, 3, 48, 24, 0, 282, 283, 5, 36, 0, 0, 283, 284, 3, 10, 5, 0, 284, 286, 1, 0, 0, 0, 285, 280, 1, 0, 0, 0, 285, 281, 1, 0, 0, 0, 286, 29, 1, 0, 0, 0, 287, 288, 5, 6, 0, 0, 288, 293, 3, 32, 16, 0, 289, 290, 5, 38, 0, 0, 290, 292, 3, 32, 16, 0, 291, 289, 1, 0, 0, 0, 292, 295, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 297, 1, 0, 0, 0, 295, 293, 1, 0, 0, 0, 296, 298, 3, 34, 17, 0, 297, 296, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 31, 1, 0, 0, 0, 299, 300, 5, 25, 0, 0, 300, 33, 1, 0, 0, 0, 301, 304, 3, 36, 18, 0, 302, 304, 3, 38, 19, 0, 303, 301, 1, 0, 0, 0, 303, 302, 1, 0, 0, 0, 304, 35, 1, 0, 0, 0, 305, 306, 5, 76, 0, 0, 306, 311, 3, 32, 16, 0, 307, 308, 5, 38, 0, 0, 308, 310, 3, 32, 16, 0, 309, 307, 1, 0, 0, 0, 310, 313, 1, 0, 0, 0, 311, 309, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 37, 1, 0, 0, 0, 313, 311, 1, 0, 0, 0, 314, 315, 5, 69, 0, 0, 315, 316, 3, 36, 18, 0, 316, 317, 5, 70, 0, 0, 317, 39, 1, 0, 0, 0, 318, 319, 5, 13, 0, 0, 319, 324, 3, 32, 16, 0, 320, 321, 5, 38, 0, 0, 321, 323, 3, 32, 16, 0, 322, 320, 1, 0, 0, 0, 323, 326, 1, 0, 0, 0, 324, 322, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 328, 1, 0, 0, 0, 326, 324, 1, 0, 0, 0, 327, 329, 3, 26, 13, 0, 328, 327, 1, 0, 0, 0, 328, 329, 1, 0, 0, 0, 329, 332, 1, 0, 0, 0, 330, 331, 5, 33, 0, 0, 331, 333, 3, 26, 13, 0, 332, 330, 1, 0, 0, 0, 332, 333, 1, 0, 0, 0, 333, 41, 1, 0, 0, 0, 334, 335, 5, 4, 0, 0, 335, 336, 3, 26, 13, 0, 336, 43, 1, 0, 0, 0, 337, 339, 5, 19, 0, 0, 338, 340, 3, 26, 13, 0, 339, 338, 1, 0, 0, 0, 339, 340, 1, 0, 0, 0, 340, 343, 1, 0, 0, 0, 341, 342, 5, 33, 0, 0, 342, 344, 3, 26, 13, 0, 343, 341, 1, 0, 0, 0, 343, 344, 1, 0, 0, 0, 344, 45, 1, 0, 0, 0, 345, 346, 5, 8, 0, 0, 346, 349, 3, 26, 13, 0, 347, 348, 5, 33, 0, 0, 348, 350, 3, 26, 13, 0, 349, 347, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 350, 47, 1, 0, 0, 0, 351, 356, 3, 54, 27, 0, 352, 353, 5, 40, 0, 0, 353, 355, 3, 54, 27, 0, 354, 352, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 49, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 359, 364, 3, 56, 28, 0, 360, 361, 5, 40, 0, 0, 361, 363, 3, 56, 28, 0, 362, 360, 1, 0, 0, 0, 363, 366, 1, 0, 0, 0, 364, 362, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 51, 1, 0, 0, 0, 366, 364, 1, 0, 0, 0, 367, 372, 3, 50, 25, 0, 368, 369, 5, 38, 0, 0, 369, 371, 3, 50, 25, 0, 370, 368, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 53, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 376, 7, 2, 0, 0, 376, 55, 1, 0, 0, 0, 377, 378, 5, 80, 0, 0, 378, 57, 1, 0, 0, 0, 379, 422, 5, 49, 0, 0, 380, 381, 3, 92, 46, 0, 381, 382, 5, 71, 0, 0, 382, 422, 1, 0, 0, 0, 383, 422, 3, 90, 45, 0, 384, 422, 3, 92, 46, 0, 385, 422, 3, 86, 43, 0, 386, 422, 3, 60, 30, 0, 387, 422, 3, 94, 47, 0, 388, 389, 5, 69, 0, 0, 389, 394, 3, 88, 44, 0, 390, 391, 5, 38, 0, 0, 391, 393, 3, 88, 44, 0, 392, 390, 1, 0, 0, 0, 393, 396, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, 394, 395, 1, 0, 0, 0, 395, 397, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, 397, 398, 5, 70, 0, 0, 398, 422, 1, 0, 0, 0, 399, 400, 5, 69, 0, 0, 400, 405, 3, 86, 43, 0, 401, 402, 5, 38, 0, 0, 402, 404, 3, 86, 43, 0, 403, 401, 1, 0, 0, 0, 404, 407, 1, 0, 0, 0, 405, 403, 1, 0, 0, 0, 405, 406, 1, 0, 0, 0, 406, 408, 1, 0, 0, 0, 407, 405, 1, 0, 0, 0, 408, 409, 5, 70, 0, 0, 409, 422, 1, 0, 0, 0, 410, 411, 5, 69, 0, 0, 411, 416, 3, 94, 47, 0, 412, 413, 5, 38, 0, 0, 413, 415, 3, 94, 47, 0, 414, 412, 1, 0, 0, 0, 415, 418, 1, 0, 0, 0, 416, 414, 1, 0, 0, 0, 416, 417, 1, 0, 0, 0, 417, 419, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 419, 420, 5, 70, 0, 0, 420, 422, 1, 0, 0, 0, 421, 379, 1, 0, 0, 0, 421, 380, 1, 0, 0, 0, 421, 383, 1, 0, 0, 0, 421, 384, 1, 0, 0, 0, 421, 385, 1, 0, 0, 0, 421, 386, 1, 0, 0, 0, 421, 387, 1, 0, 0, 0, 421, 388, 1, 0, 0, 0, 421, 399, 1, 0, 0, 0, 421, 410, 1, 0, 0, 0, 422, 59, 1, 0, 0, 0, 423, 426, 5, 52, 0, 0, 424, 426, 5, 68, 0, 0, 425, 423, 1, 0, 0, 0, 425, 424, 1, 0, 0, 0, 426, 61, 1, 0, 0, 0, 427, 428, 5, 10, 0, 0, 428, 429, 5, 31, 0, 0, 429, 63, 1, 0, 0, 0, 430, 431, 5, 18, 0, 0, 431, 436, 3, 66, 33, 0, 432, 433, 5, 38, 0, 0, 433, 435, 3, 66, 33, 0, 434, 432, 1, 0, 0, 0, 435, 438, 1, 0, 0, 0, 436, 434, 1, 0, 0, 0, 436, 437, 1, 0, 0, 0, 437, 65, 1, 0, 0, 0, 438, 436, 1, 0, 0, 0, 439, 441, 3, 10, 5, 0, 440, 442, 7, 3, 0, 0, 441, 440, 1, 0, 0, 0, 441, 442, 1, 0, 0, 0, 442, 445, 1, 0, 0, 0, 443, 444, 5, 50, 0, 0, 444, 446, 7, 4, 0, 0, 445, 443, 1, 0, 0, 0, 445, 446, 1, 0, 0, 0, 446, 67, 1, 0, 0, 0, 447, 448, 5, 9, 0, 0, 448, 449, 3, 52, 26, 0, 449, 69, 1, 0, 0, 0, 450, 451, 5, 2, 0, 0, 451, 452, 3, 52, 26, 0, 452, 71, 1, 0, 0, 0, 453, 454, 5, 15, 0, 0, 454, 459, 3, 74, 37, 0, 455, 456, 5, 38, 0, 0, 456, 458, 3, 74, 37, 0, 457, 455, 1, 0, 0, 0, 458, 461, 1, 0, 0, 0, 459, 457, 1, 0, 0, 0, 459, 460, 1, 0, 0, 0, 460, 73, 1, 0, 0, 0, 461, 459, 1, 0, 0, 0, 462, 463, 3, 50, 25, 0, 463, 464, 5, 84, 0, 0, 464, 465, 3, 50, 25, 0, 465, 75, 1, 0, 0, 0, 466, 467, 5, 1, 0, 0, 467, 468, 3, 18, 9, 0, 468, 470, 3, 94, 47, 0, 469, 471, 3, 82, 41, 0, 470, 469, 1, 0, 0, 0, 470, 471, 1, 0, 0, 0, 471, 77, 1, 0, 0, 0, 472, 473, 5, 7, 0, 0, 473, 474, 3, 18, 9, 0, 474, 475, 3, 94, 47, 0, 475, 79, 1, 0, 0, 0, 476, 477, 5, 14, 0, 0, 477, 478, 3, 48, 24, 0, 478, 81, 1, 0, 0, 0, 479, 484, 3, 84, 42, 0, 480, 481, 5, 38, 0, 0, 481, 483, 3, 84, 42, 0, 482, 480, 1, 0, 0, 0, 483, 486, 1, 0, 0, 0, 484, 482, 1, 0, 0, 0, 484, 485, 1, 0, 0, 0, 485, 83, 1, 0, 0, 0, 486, 484, 1, 0, 0, 0, 487, 488, 3, 54, 27, 0, 488, 489, 5, 36, 0, 0, 489, 490, 3, 58, 29, 0, 490, 85, 1, 0, 0, 0, 491, 492, 7, 5, 0, 0, 492, 87, 1, 0, 0, 0, 493, 496, 3, 90, 45, 0, 494, 496, 3, 92, 46, 0, 495, 493, 1, 0, 0, 0, 495, 494, 1, 0, 0, 0, 496, 89, 1, 0, 0, 0, 497, 499, 7, 0, 0, 0, 498, 497, 1, 0, 0, 0, 498, 499, 1, 0, 0, 0, 499, 500, 1, 0, 0, 0, 500, 501, 5, 32, 0, 0, 501, 91, 1, 0, 0, 0, 502, 504, 7, 0, 0, 0, 503, 502, 1, 0, 0, 0, 503, 504, 1, 0, 0, 0, 504, 505, 1, 0, 0, 0, 505, 506, 5, 31, 0, 0, 506, 93, 1, 0, 0, 0, 507, 508, 5, 30, 0, 0, 508, 95, 1, 0, 0, 0, 509, 510, 7, 6, 0, 0, 510, 97, 1, 0, 0, 0, 511, 512, 5, 5, 0, 0, 512, 513, 3, 100, 50, 0, 513, 99, 1, 0, 0, 0, 514, 515, 5, 69, 0, 0, 515, 516, 3, 2, 1, 0, 516, 517, 5, 70, 0, 0, 517, 101, 1, 0, 0, 0, 518, 519, 5, 17, 0, 0, 519, 520, 5, 106, 0, 0, 520, 103, 1, 0, 0, 0, 521, 522, 5, 12, 0, 0, 522, 523, 5, 110, 0, 0, 523, 105, 1, 0, 0, 0, 524, 525, 5, 3, 0, 0, 525, 528, 5, 90, 0, 0, 526, 527, 5, 88, 0, 0, 527, 529, 3, 50, 25, 0, 528, 526, 1, 0, 0, 0, 528, 529, 1, 0, 0, 0, 529, 539, 1, 0, 0, 0, 530, 531, 5, 89, 0, 0, 531, 536, 3, 108, 54, 0, 532, 533, 5, 38, 0, 0, 533, 535, 3, 108, 54, 0, 534, 532, 1, 0, 0, 0, 535, 538, 1, 0, 0, 0, 536, 534, 1, 0, 0, 0, 536, 537, 1, 0, 0, 0, 537, 540, 1, 0, 0, 0, 538, 536, 1, 0, 0, 0, 539, 530, 1, 0, 0, 0, 539, 540, 1, 0, 0, 0, 540, 107, 1, 0, 0, 0, 541, 542, 3, 50, 25, 0, 542, 543, 5, 36, 0, 0, 543, 545, 1, 0, 0, 0, 544, 541, 1, 0, 0, 0, 544, 545, 1, 0, 0, 0, 545, 546, 1, 0, 0, 0, 546, 547, 3, 50, 25, 0, 547, 109, 1, 0, 0, 0, 548, 549, 5, 11, 0, 0, 549, 550, 5, 25, 0, 0, 550, 551, 5, 88, 0, 0, 551, 552, 3, 52, 26, 0, 552, 111, 1, 0, 0, 0, 53, 123, 132, 148, 160, 169, 177, 181, 189, 191, 196, 203, 208, 215, 221, 229, 231, 242, 249, 260, 263, 277, 285, 293, 297, 303, 311, 324, 328, 332, 339, 343, 349, 356, 364, 372, 394, 405, 416, 421, 425, 436, 441, 445, 459, 470, 484, 495, 498, 503, 528, 536, 539, 544] \ No newline at end of file diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java index 1c136a946a0f..6c21529d6a64 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java @@ -26,22 +26,23 @@ public class EsqlBaseParser extends Parser { CAST_OP=37, COMMA=38, DESC=39, DOT=40, FALSE=41, FIRST=42, LAST=43, LP=44, IN=45, IS=46, LIKE=47, NOT=48, NULL=49, NULLS=50, OR=51, PARAM=52, RLIKE=53, RP=54, TRUE=55, EQ=56, CIEQ=57, NEQ=58, LT=59, LTE=60, GT=61, GTE=62, - PLUS=63, MINUS=64, ASTERISK=65, SLASH=66, PERCENT=67, OPENING_BRACKET=68, - CLOSING_BRACKET=69, UNQUOTED_IDENTIFIER=70, QUOTED_IDENTIFIER=71, EXPR_LINE_COMMENT=72, - EXPR_MULTILINE_COMMENT=73, EXPR_WS=74, METADATA=75, FROM_LINE_COMMENT=76, - FROM_MULTILINE_COMMENT=77, FROM_WS=78, ID_PATTERN=79, PROJECT_LINE_COMMENT=80, - PROJECT_MULTILINE_COMMENT=81, PROJECT_WS=82, AS=83, RENAME_LINE_COMMENT=84, - RENAME_MULTILINE_COMMENT=85, RENAME_WS=86, ON=87, WITH=88, ENRICH_POLICY_NAME=89, - ENRICH_LINE_COMMENT=90, ENRICH_MULTILINE_COMMENT=91, ENRICH_WS=92, ENRICH_FIELD_LINE_COMMENT=93, - ENRICH_FIELD_MULTILINE_COMMENT=94, ENRICH_FIELD_WS=95, LOOKUP_LINE_COMMENT=96, - LOOKUP_MULTILINE_COMMENT=97, LOOKUP_WS=98, LOOKUP_FIELD_LINE_COMMENT=99, - LOOKUP_FIELD_MULTILINE_COMMENT=100, LOOKUP_FIELD_WS=101, MVEXPAND_LINE_COMMENT=102, - MVEXPAND_MULTILINE_COMMENT=103, MVEXPAND_WS=104, INFO=105, SHOW_LINE_COMMENT=106, - SHOW_MULTILINE_COMMENT=107, SHOW_WS=108, FUNCTIONS=109, META_LINE_COMMENT=110, - META_MULTILINE_COMMENT=111, META_WS=112, COLON=113, SETTING=114, SETTING_LINE_COMMENT=115, - SETTTING_MULTILINE_COMMENT=116, SETTING_WS=117, METRICS_LINE_COMMENT=118, - METRICS_MULTILINE_COMMENT=119, METRICS_WS=120, CLOSING_METRICS_LINE_COMMENT=121, - CLOSING_METRICS_MULTILINE_COMMENT=122, CLOSING_METRICS_WS=123; + PLUS=63, MINUS=64, ASTERISK=65, SLASH=66, PERCENT=67, NAMED_OR_POSITIONAL_PARAM=68, + OPENING_BRACKET=69, CLOSING_BRACKET=70, UNQUOTED_IDENTIFIER=71, QUOTED_IDENTIFIER=72, + EXPR_LINE_COMMENT=73, EXPR_MULTILINE_COMMENT=74, EXPR_WS=75, METADATA=76, + FROM_LINE_COMMENT=77, FROM_MULTILINE_COMMENT=78, FROM_WS=79, ID_PATTERN=80, + PROJECT_LINE_COMMENT=81, PROJECT_MULTILINE_COMMENT=82, PROJECT_WS=83, + AS=84, RENAME_LINE_COMMENT=85, RENAME_MULTILINE_COMMENT=86, RENAME_WS=87, + ON=88, WITH=89, ENRICH_POLICY_NAME=90, ENRICH_LINE_COMMENT=91, ENRICH_MULTILINE_COMMENT=92, + ENRICH_WS=93, ENRICH_FIELD_LINE_COMMENT=94, ENRICH_FIELD_MULTILINE_COMMENT=95, + ENRICH_FIELD_WS=96, LOOKUP_LINE_COMMENT=97, LOOKUP_MULTILINE_COMMENT=98, + LOOKUP_WS=99, LOOKUP_FIELD_LINE_COMMENT=100, LOOKUP_FIELD_MULTILINE_COMMENT=101, + LOOKUP_FIELD_WS=102, MVEXPAND_LINE_COMMENT=103, MVEXPAND_MULTILINE_COMMENT=104, + MVEXPAND_WS=105, INFO=106, SHOW_LINE_COMMENT=107, SHOW_MULTILINE_COMMENT=108, + SHOW_WS=109, FUNCTIONS=110, META_LINE_COMMENT=111, META_MULTILINE_COMMENT=112, + META_WS=113, COLON=114, SETTING=115, SETTING_LINE_COMMENT=116, SETTTING_MULTILINE_COMMENT=117, + SETTING_WS=118, METRICS_LINE_COMMENT=119, METRICS_MULTILINE_COMMENT=120, + METRICS_WS=121, CLOSING_METRICS_LINE_COMMENT=122, CLOSING_METRICS_MULTILINE_COMMENT=123, + CLOSING_METRICS_WS=124; public static final int RULE_singleStatement = 0, RULE_query = 1, RULE_sourceCommand = 2, RULE_processingCommand = 3, RULE_whereCommand = 4, RULE_booleanExpression = 5, RULE_regexBooleanExpression = 6, @@ -52,15 +53,15 @@ public class EsqlBaseParser extends Parser { RULE_metricsCommand = 20, RULE_evalCommand = 21, RULE_statsCommand = 22, RULE_inlinestatsCommand = 23, RULE_qualifiedName = 24, RULE_qualifiedNamePattern = 25, RULE_qualifiedNamePatterns = 26, RULE_identifier = 27, RULE_identifierPattern = 28, - RULE_constant = 29, RULE_limitCommand = 30, RULE_sortCommand = 31, RULE_orderExpression = 32, - RULE_keepCommand = 33, RULE_dropCommand = 34, RULE_renameCommand = 35, - RULE_renameClause = 36, RULE_dissectCommand = 37, RULE_grokCommand = 38, - RULE_mvExpandCommand = 39, RULE_commandOptions = 40, RULE_commandOption = 41, - RULE_booleanValue = 42, RULE_numericValue = 43, RULE_decimalValue = 44, - RULE_integerValue = 45, RULE_string = 46, RULE_comparisonOperator = 47, - RULE_explainCommand = 48, RULE_subqueryExpression = 49, RULE_showCommand = 50, - RULE_metaCommand = 51, RULE_enrichCommand = 52, RULE_enrichWithClause = 53, - RULE_lookupCommand = 54; + RULE_constant = 29, RULE_params = 30, RULE_limitCommand = 31, RULE_sortCommand = 32, + RULE_orderExpression = 33, RULE_keepCommand = 34, RULE_dropCommand = 35, + RULE_renameCommand = 36, RULE_renameClause = 37, RULE_dissectCommand = 38, + RULE_grokCommand = 39, RULE_mvExpandCommand = 40, RULE_commandOptions = 41, + RULE_commandOption = 42, RULE_booleanValue = 43, RULE_numericValue = 44, + RULE_decimalValue = 45, RULE_integerValue = 46, RULE_string = 47, RULE_comparisonOperator = 48, + RULE_explainCommand = 49, RULE_subqueryExpression = 50, RULE_showCommand = 51, + RULE_metaCommand = 52, RULE_enrichCommand = 53, RULE_enrichWithClause = 54, + RULE_lookupCommand = 55; private static String[] makeRuleNames() { return new String[] { "singleStatement", "query", "sourceCommand", "processingCommand", "whereCommand", @@ -69,9 +70,9 @@ public class EsqlBaseParser extends Parser { "fields", "field", "fromCommand", "indexIdentifier", "metadata", "metadataOption", "deprecated_metadata", "metricsCommand", "evalCommand", "statsCommand", "inlinestatsCommand", "qualifiedName", "qualifiedNamePattern", "qualifiedNamePatterns", - "identifier", "identifierPattern", "constant", "limitCommand", "sortCommand", - "orderExpression", "keepCommand", "dropCommand", "renameCommand", "renameClause", - "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions", + "identifier", "identifierPattern", "constant", "params", "limitCommand", + "sortCommand", "orderExpression", "keepCommand", "dropCommand", "renameCommand", + "renameClause", "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions", "commandOption", "booleanValue", "numericValue", "decimalValue", "integerValue", "string", "comparisonOperator", "explainCommand", "subqueryExpression", "showCommand", "metaCommand", "enrichCommand", "enrichWithClause", "lookupCommand" @@ -89,11 +90,11 @@ public class EsqlBaseParser extends Parser { "'desc'", "'.'", "'false'", "'first'", "'last'", "'('", "'in'", "'is'", "'like'", "'not'", "'null'", "'nulls'", "'or'", "'?'", "'rlike'", "')'", "'true'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", - "'-'", "'*'", "'/'", "'%'", null, "']'", null, null, null, null, null, - "'metadata'", null, null, null, null, null, null, null, "'as'", null, - null, null, "'on'", "'with'", null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, "'info'", null, - null, null, "'functions'", null, null, null, "':'" + "'-'", "'*'", "'/'", "'%'", null, null, "']'", null, null, null, null, + null, "'metadata'", null, null, null, null, null, null, null, "'as'", + null, null, null, "'on'", "'with'", null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, "'info'", + null, null, null, "'functions'", null, null, null, "':'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); @@ -108,21 +109,21 @@ public class EsqlBaseParser extends Parser { "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", - "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", - "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", - "METADATA", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", "FROM_WS", - "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", - "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", "RENAME_WS", - "ON", "WITH", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", - "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", - "ENRICH_FIELD_WS", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT", - "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT", - "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", - "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", - "SHOW_WS", "FUNCTIONS", "META_LINE_COMMENT", "META_MULTILINE_COMMENT", - "META_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT", "SETTTING_MULTILINE_COMMENT", - "SETTING_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT", "METRICS_WS", - "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT", + "PERCENT", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET", "CLOSING_BRACKET", + "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", + "EXPR_WS", "METADATA", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", + "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT", + "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", + "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "LOOKUP_LINE_COMMENT", + "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", + "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", + "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT", + "SHOW_MULTILINE_COMMENT", "SHOW_WS", "FUNCTIONS", "META_LINE_COMMENT", + "META_MULTILINE_COMMENT", "META_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT", + "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT", + "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT", "CLOSING_METRICS_WS" }; } @@ -210,9 +211,9 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(110); + setState(112); query(0); - setState(111); + setState(113); match(EOF); } } @@ -308,11 +309,11 @@ public class EsqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(114); + setState(116); sourceCommand(); } _ctx.stop = _input.LT(-1); - setState(121); + setState(123); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,0,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -323,16 +324,16 @@ public class EsqlBaseParser extends Parser { { _localctx = new CompositeQueryContext(new QueryContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_query); - setState(116); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(117); - match(PIPE); setState(118); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(119); + match(PIPE); + setState(120); processingCommand(); } } } - setState(123); + setState(125); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,0,_ctx); } @@ -393,48 +394,48 @@ public class EsqlBaseParser extends Parser { SourceCommandContext _localctx = new SourceCommandContext(_ctx, getState()); enterRule(_localctx, 4, RULE_sourceCommand); try { - setState(130); + setState(132); _errHandler.sync(this); switch (_input.LA(1)) { case EXPLAIN: enterOuterAlt(_localctx, 1); { - setState(124); + setState(126); explainCommand(); } break; case FROM: enterOuterAlt(_localctx, 2); { - setState(125); + setState(127); fromCommand(); } break; case ROW: enterOuterAlt(_localctx, 3); { - setState(126); + setState(128); rowCommand(); } break; case METRICS: enterOuterAlt(_localctx, 4); { - setState(127); + setState(129); metricsCommand(); } break; case SHOW: enterOuterAlt(_localctx, 5); { - setState(128); + setState(130); showCommand(); } break; case META: enterOuterAlt(_localctx, 6); { - setState(129); + setState(131); metaCommand(); } break; @@ -521,104 +522,104 @@ public class EsqlBaseParser extends Parser { ProcessingCommandContext _localctx = new ProcessingCommandContext(_ctx, getState()); enterRule(_localctx, 6, RULE_processingCommand); try { - setState(146); + setState(148); _errHandler.sync(this); switch (_input.LA(1)) { case EVAL: enterOuterAlt(_localctx, 1); { - setState(132); + setState(134); evalCommand(); } break; case INLINESTATS: enterOuterAlt(_localctx, 2); { - setState(133); + setState(135); inlinestatsCommand(); } break; case LIMIT: enterOuterAlt(_localctx, 3); { - setState(134); + setState(136); limitCommand(); } break; case LOOKUP: enterOuterAlt(_localctx, 4); { - setState(135); + setState(137); lookupCommand(); } break; case KEEP: enterOuterAlt(_localctx, 5); { - setState(136); + setState(138); keepCommand(); } break; case SORT: enterOuterAlt(_localctx, 6); { - setState(137); + setState(139); sortCommand(); } break; case STATS: enterOuterAlt(_localctx, 7); { - setState(138); + setState(140); statsCommand(); } break; case WHERE: enterOuterAlt(_localctx, 8); { - setState(139); + setState(141); whereCommand(); } break; case DROP: enterOuterAlt(_localctx, 9); { - setState(140); + setState(142); dropCommand(); } break; case RENAME: enterOuterAlt(_localctx, 10); { - setState(141); + setState(143); renameCommand(); } break; case DISSECT: enterOuterAlt(_localctx, 11); { - setState(142); + setState(144); dissectCommand(); } break; case GROK: enterOuterAlt(_localctx, 12); { - setState(143); + setState(145); grokCommand(); } break; case ENRICH: enterOuterAlt(_localctx, 13); { - setState(144); + setState(146); enrichCommand(); } break; case MV_EXPAND: enterOuterAlt(_localctx, 14); { - setState(145); + setState(147); mvExpandCommand(); } break; @@ -669,9 +670,9 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(148); + setState(150); match(WHERE); - setState(149); + setState(151); booleanExpression(0); } } @@ -866,7 +867,7 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(179); + setState(181); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { case 1: @@ -875,9 +876,9 @@ public class EsqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(152); + setState(154); match(NOT); - setState(153); + setState(155); booleanExpression(7); } break; @@ -886,7 +887,7 @@ public class EsqlBaseParser extends Parser { _localctx = new BooleanDefaultContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(154); + setState(156); valueExpression(); } break; @@ -895,7 +896,7 @@ public class EsqlBaseParser extends Parser { _localctx = new RegexExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(155); + setState(157); regexBooleanExpression(); } break; @@ -904,41 +905,41 @@ public class EsqlBaseParser extends Parser { _localctx = new LogicalInContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(156); - valueExpression(); setState(158); + valueExpression(); + setState(160); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(157); + setState(159); match(NOT); } } - setState(160); - match(IN); - setState(161); - match(LP); setState(162); + match(IN); + setState(163); + match(LP); + setState(164); valueExpression(); - setState(167); + setState(169); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(163); + setState(165); match(COMMA); - setState(164); + setState(166); valueExpression(); } } - setState(169); + setState(171); _errHandler.sync(this); _la = _input.LA(1); } - setState(170); + setState(172); match(RP); } break; @@ -947,27 +948,27 @@ public class EsqlBaseParser extends Parser { _localctx = new IsNullContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(172); + setState(174); valueExpression(); - setState(173); - match(IS); setState(175); + match(IS); + setState(177); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(174); + setState(176); match(NOT); } } - setState(177); + setState(179); match(NULL); } break; } _ctx.stop = _input.LT(-1); - setState(189); + setState(191); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,8,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -975,7 +976,7 @@ public class EsqlBaseParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(187); + setState(189); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { case 1: @@ -983,11 +984,11 @@ public class EsqlBaseParser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(181); - if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); - setState(182); - ((LogicalBinaryContext)_localctx).operator = match(AND); setState(183); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(184); + ((LogicalBinaryContext)_localctx).operator = match(AND); + setState(185); ((LogicalBinaryContext)_localctx).right = booleanExpression(5); } break; @@ -996,18 +997,18 @@ public class EsqlBaseParser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(184); - if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(185); - ((LogicalBinaryContext)_localctx).operator = match(OR); setState(186); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(187); + ((LogicalBinaryContext)_localctx).operator = match(OR); + setState(188); ((LogicalBinaryContext)_localctx).right = booleanExpression(4); } break; } } } - setState(191); + setState(193); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,8,_ctx); } @@ -1062,48 +1063,48 @@ public class EsqlBaseParser extends Parser { enterRule(_localctx, 12, RULE_regexBooleanExpression); int _la; try { - setState(206); + setState(208); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(192); - valueExpression(); setState(194); + valueExpression(); + setState(196); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(193); + setState(195); match(NOT); } } - setState(196); + setState(198); ((RegexBooleanExpressionContext)_localctx).kind = match(LIKE); - setState(197); + setState(199); ((RegexBooleanExpressionContext)_localctx).pattern = string(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(199); - valueExpression(); setState(201); + valueExpression(); + setState(203); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(200); + setState(202); match(NOT); } } - setState(203); + setState(205); ((RegexBooleanExpressionContext)_localctx).kind = match(RLIKE); - setState(204); + setState(206); ((RegexBooleanExpressionContext)_localctx).pattern = string(); } break; @@ -1189,14 +1190,14 @@ public class EsqlBaseParser extends Parser { ValueExpressionContext _localctx = new ValueExpressionContext(_ctx, getState()); enterRule(_localctx, 14, RULE_valueExpression); try { - setState(213); + setState(215); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { case 1: _localctx = new ValueExpressionDefaultContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(208); + setState(210); operatorExpression(0); } break; @@ -1204,11 +1205,11 @@ public class EsqlBaseParser extends Parser { _localctx = new ComparisonContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(209); - ((ComparisonContext)_localctx).left = operatorExpression(0); - setState(210); - comparisonOperator(); setState(211); + ((ComparisonContext)_localctx).left = operatorExpression(0); + setState(212); + comparisonOperator(); + setState(213); ((ComparisonContext)_localctx).right = operatorExpression(0); } break; @@ -1333,7 +1334,7 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(219); + setState(221); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { case 1: @@ -1342,7 +1343,7 @@ public class EsqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(216); + setState(218); primaryExpression(0); } break; @@ -1351,7 +1352,7 @@ public class EsqlBaseParser extends Parser { _localctx = new ArithmeticUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(217); + setState(219); ((ArithmeticUnaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -1362,13 +1363,13 @@ public class EsqlBaseParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(218); + setState(220); operatorExpression(3); } break; } _ctx.stop = _input.LT(-1); - setState(229); + setState(231); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,15,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -1376,7 +1377,7 @@ public class EsqlBaseParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(227); + setState(229); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { case 1: @@ -1384,9 +1385,9 @@ public class EsqlBaseParser extends Parser { _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression); - setState(221); + setState(223); if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(222); + setState(224); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(((((_la - 65)) & ~0x3f) == 0 && ((1L << (_la - 65)) & 7L) != 0)) ) { @@ -1397,7 +1398,7 @@ public class EsqlBaseParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(223); + setState(225); ((ArithmeticBinaryContext)_localctx).right = operatorExpression(3); } break; @@ -1406,9 +1407,9 @@ public class EsqlBaseParser extends Parser { _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression); - setState(224); + setState(226); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(225); + setState(227); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -1419,14 +1420,14 @@ public class EsqlBaseParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(226); + setState(228); ((ArithmeticBinaryContext)_localctx).right = operatorExpression(2); } break; } } } - setState(231); + setState(233); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,15,_ctx); } @@ -1584,7 +1585,7 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(240); + setState(242); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { case 1: @@ -1593,7 +1594,7 @@ public class EsqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(233); + setState(235); constant(); } break; @@ -1602,7 +1603,7 @@ public class EsqlBaseParser extends Parser { _localctx = new DereferenceContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(234); + setState(236); qualifiedName(); } break; @@ -1611,7 +1612,7 @@ public class EsqlBaseParser extends Parser { _localctx = new FunctionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(235); + setState(237); functionExpression(); } break; @@ -1620,17 +1621,17 @@ public class EsqlBaseParser extends Parser { _localctx = new ParenthesizedExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(236); - match(LP); - setState(237); - booleanExpression(0); setState(238); + match(LP); + setState(239); + booleanExpression(0); + setState(240); match(RP); } break; } _ctx.stop = _input.LT(-1); - setState(247); + setState(249); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,17,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -1641,16 +1642,16 @@ public class EsqlBaseParser extends Parser { { _localctx = new InlineCastContext(new PrimaryExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_primaryExpression); - setState(242); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(243); - match(CAST_OP); setState(244); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(245); + match(CAST_OP); + setState(246); dataType(); } } } - setState(249); + setState(251); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,17,_ctx); } @@ -1712,16 +1713,16 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(250); + setState(252); identifier(); - setState(251); + setState(253); match(LP); - setState(261); + setState(263); _errHandler.sync(this); switch (_input.LA(1)) { case ASTERISK: { - setState(252); + setState(254); match(ASTERISK); } break; @@ -1736,26 +1737,27 @@ public class EsqlBaseParser extends Parser { case TRUE: case PLUS: case MINUS: + case NAMED_OR_POSITIONAL_PARAM: case OPENING_BRACKET: case UNQUOTED_IDENTIFIER: case QUOTED_IDENTIFIER: { { - setState(253); + setState(255); booleanExpression(0); - setState(258); + setState(260); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(254); + setState(256); match(COMMA); - setState(255); + setState(257); booleanExpression(0); } } - setState(260); + setState(262); _errHandler.sync(this); _la = _input.LA(1); } @@ -1767,7 +1769,7 @@ public class EsqlBaseParser extends Parser { default: break; } - setState(263); + setState(265); match(RP); } } @@ -1825,7 +1827,7 @@ public class EsqlBaseParser extends Parser { _localctx = new ToDataTypeContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(265); + setState(267); identifier(); } } @@ -1872,9 +1874,9 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(267); + setState(269); match(ROW); - setState(268); + setState(270); fields(); } } @@ -1928,23 +1930,23 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(270); + setState(272); field(); - setState(275); + setState(277); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,20,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(271); + setState(273); match(COMMA); - setState(272); + setState(274); field(); } } } - setState(277); + setState(279); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,20,_ctx); } @@ -1994,24 +1996,24 @@ public class EsqlBaseParser extends Parser { FieldContext _localctx = new FieldContext(_ctx, getState()); enterRule(_localctx, 28, RULE_field); try { - setState(283); + setState(285); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(278); + setState(280); booleanExpression(0); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(279); - qualifiedName(); - setState(280); - match(ASSIGN); setState(281); + qualifiedName(); + setState(282); + match(ASSIGN); + setState(283); booleanExpression(0); } break; @@ -2071,34 +2073,34 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(285); + setState(287); match(FROM); - setState(286); + setState(288); indexIdentifier(); - setState(291); + setState(293); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,22,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(287); + setState(289); match(COMMA); - setState(288); + setState(290); indexIdentifier(); } } } - setState(293); + setState(295); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,22,_ctx); } - setState(295); + setState(297); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) { case 1: { - setState(294); + setState(296); metadata(); } break; @@ -2145,7 +2147,7 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(297); + setState(299); match(INDEX_UNQUOTED_IDENTIFIER); } } @@ -2192,20 +2194,20 @@ public class EsqlBaseParser extends Parser { MetadataContext _localctx = new MetadataContext(_ctx, getState()); enterRule(_localctx, 34, RULE_metadata); try { - setState(301); + setState(303); _errHandler.sync(this); switch (_input.LA(1)) { case METADATA: enterOuterAlt(_localctx, 1); { - setState(299); + setState(301); metadataOption(); } break; case OPENING_BRACKET: enterOuterAlt(_localctx, 2); { - setState(300); + setState(302); deprecated_metadata(); } break; @@ -2264,25 +2266,25 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(303); + setState(305); match(METADATA); - setState(304); + setState(306); indexIdentifier(); - setState(309); + setState(311); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,25,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(305); + setState(307); match(COMMA); - setState(306); + setState(308); indexIdentifier(); } } } - setState(311); + setState(313); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,25,_ctx); } @@ -2331,11 +2333,11 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(312); - match(OPENING_BRACKET); - setState(313); - metadataOption(); setState(314); + match(OPENING_BRACKET); + setState(315); + metadataOption(); + setState(316); match(CLOSING_BRACKET); } } @@ -2399,46 +2401,46 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(316); + setState(318); match(METRICS); - setState(317); + setState(319); indexIdentifier(); - setState(322); + setState(324); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,26,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(318); + setState(320); match(COMMA); - setState(319); + setState(321); indexIdentifier(); } } } - setState(324); + setState(326); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,26,_ctx); } - setState(326); + setState(328); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,27,_ctx) ) { case 1: { - setState(325); + setState(327); ((MetricsCommandContext)_localctx).aggregates = fields(); } break; } - setState(330); + setState(332); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) { case 1: { - setState(328); + setState(330); match(BY); - setState(329); + setState(331); ((MetricsCommandContext)_localctx).grouping = fields(); } break; @@ -2488,9 +2490,9 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(332); + setState(334); match(EVAL); - setState(333); + setState(335); fields(); } } @@ -2543,26 +2545,26 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(335); - match(STATS); setState(337); + match(STATS); + setState(339); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) { case 1: { - setState(336); + setState(338); ((StatsCommandContext)_localctx).stats = fields(); } break; } - setState(341); + setState(343); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) { case 1: { - setState(339); + setState(341); match(BY); - setState(340); + setState(342); ((StatsCommandContext)_localctx).grouping = fields(); } break; @@ -2618,18 +2620,18 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(343); + setState(345); match(INLINESTATS); - setState(344); + setState(346); ((InlinestatsCommandContext)_localctx).stats = fields(); - setState(347); + setState(349); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { case 1: { - setState(345); + setState(347); match(BY); - setState(346); + setState(348); ((InlinestatsCommandContext)_localctx).grouping = fields(); } break; @@ -2686,23 +2688,23 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(349); + setState(351); identifier(); - setState(354); + setState(356); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,32,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(350); + setState(352); match(DOT); - setState(351); + setState(353); identifier(); } } } - setState(356); + setState(358); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,32,_ctx); } @@ -2758,23 +2760,23 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(357); + setState(359); identifierPattern(); - setState(362); + setState(364); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,33,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(358); + setState(360); match(DOT); - setState(359); + setState(361); identifierPattern(); } } } - setState(364); + setState(366); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,33,_ctx); } @@ -2830,23 +2832,23 @@ public class EsqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(365); + setState(367); qualifiedNamePattern(); - setState(370); + setState(372); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,34,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(366); + setState(368); match(COMMA); - setState(367); + setState(369); qualifiedNamePattern(); } } } - setState(372); + setState(374); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,34,_ctx); } @@ -2894,7 +2896,7 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(373); + setState(375); _la = _input.LA(1); if ( !(_la==UNQUOTED_IDENTIFIER || _la==QUOTED_IDENTIFIER) ) { _errHandler.recoverInline(this); @@ -2946,7 +2948,7 @@ public class EsqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(375); + setState(377); match(ID_PATTERN); } } @@ -3149,21 +3151,23 @@ public class EsqlBaseParser extends Parser { } } @SuppressWarnings("CheckReturnValue") - public static class InputParamContext extends ConstantContext { - public TerminalNode PARAM() { return getToken(EsqlBaseParser.PARAM, 0); } + public static class InputParamsContext extends ConstantContext { + public ParamsContext params() { + return getRuleContext(ParamsContext.class,0); + } @SuppressWarnings("this-escape") - public InputParamContext(ConstantContext ctx) { copyFrom(ctx); } + public InputParamsContext(ConstantContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterInputParam(this); + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterInputParams(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitInputParam(this); + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitInputParams(this); } @Override public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitInputParam(this); + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitInputParams(this); else return visitor.visitChildren(this); } } @@ -3215,14 +3219,14 @@ public class EsqlBaseParser extends Parser { enterRule(_localctx, 58, RULE_constant); int _la; try { - setState(419); + setState(421); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) { case 1: _localctx = new NullLiteralContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(377); + setState(379); match(NULL); } break; @@ -3230,9 +3234,9 @@ public class EsqlBaseParser extends Parser { _localctx = new QualifiedIntegerLiteralContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(378); + setState(380); integerValue(); - setState(379); + setState(381); match(UNQUOTED_IDENTIFIER); } break; @@ -3240,7 +3244,7 @@ public class EsqlBaseParser extends Parser { _localctx = new DecimalLiteralContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(381); + setState(383); decimalValue(); } break; @@ -3248,7 +3252,7 @@ public class EsqlBaseParser extends Parser { _localctx = new IntegerLiteralContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(382); + setState(384); integerValue(); } break; @@ -3256,23 +3260,23 @@ public class EsqlBaseParser extends Parser { _localctx = new BooleanLiteralContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(383); + setState(385); booleanValue(); } break; case 6: - _localctx = new InputParamContext(_localctx); + _localctx = new InputParamsContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(384); - match(PARAM); + setState(386); + params(); } break; case 7: _localctx = new StringLiteralContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(385); + setState(387); string(); } break; @@ -3280,27 +3284,27 @@ public class EsqlBaseParser extends Parser { _localctx = new NumericArrayLiteralContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(386); + setState(388); match(OPENING_BRACKET); - setState(387); + setState(389); numericValue(); - setState(392); + setState(394); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(388); + setState(390); match(COMMA); - setState(389); + setState(391); numericValue(); } } - setState(394); + setState(396); _errHandler.sync(this); _la = _input.LA(1); } - setState(395); + setState(397); match(CLOSING_BRACKET); } break; @@ -3308,27 +3312,27 @@ public class EsqlBaseParser extends Parser { _localctx = new BooleanArrayLiteralContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(397); + setState(399); match(OPENING_BRACKET); - setState(398); + setState(400); booleanValue(); - setState(403); + setState(405); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(399); + setState(401); match(COMMA); - setState(400); + setState(402); booleanValue(); } } - setState(405); + setState(407); _errHandler.sync(this); _la = _input.LA(1); } - setState(406); + setState(408); match(CLOSING_BRACKET); } break; @@ -3336,27 +3340,27 @@ public class EsqlBaseParser extends Parser { _localctx = new StringArrayLiteralContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(408); + setState(410); match(OPENING_BRACKET); - setState(409); + setState(411); string(); - setState(414); + setState(416); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(410); + setState(412); match(COMMA); - setState(411); + setState(413); string(); } } - setState(416); + setState(418); _errHandler.sync(this); _la = _input.LA(1); } - setState(417); + setState(419); match(CLOSING_BRACKET); } break; @@ -3373,6 +3377,97 @@ public class EsqlBaseParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") + public static class ParamsContext extends ParserRuleContext { + @SuppressWarnings("this-escape") + public ParamsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_params; } + + @SuppressWarnings("this-escape") + public ParamsContext() { } + public void copyFrom(ParamsContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class InputNamedOrPositionalParamContext extends ParamsContext { + public TerminalNode NAMED_OR_POSITIONAL_PARAM() { return getToken(EsqlBaseParser.NAMED_OR_POSITIONAL_PARAM, 0); } + @SuppressWarnings("this-escape") + public InputNamedOrPositionalParamContext(ParamsContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterInputNamedOrPositionalParam(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitInputNamedOrPositionalParam(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitInputNamedOrPositionalParam(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class InputParamContext extends ParamsContext { + public TerminalNode PARAM() { return getToken(EsqlBaseParser.PARAM, 0); } + @SuppressWarnings("this-escape") + public InputParamContext(ParamsContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterInputParam(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitInputParam(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitInputParam(this); + else return visitor.visitChildren(this); + } + } + + public final ParamsContext params() throws RecognitionException { + ParamsContext _localctx = new ParamsContext(_ctx, getState()); + enterRule(_localctx, 60, RULE_params); + try { + setState(425); + _errHandler.sync(this); + switch (_input.LA(1)) { + case PARAM: + _localctx = new InputParamContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(423); + match(PARAM); + } + break; + case NAMED_OR_POSITIONAL_PARAM: + _localctx = new InputNamedOrPositionalParamContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(424); + match(NAMED_OR_POSITIONAL_PARAM); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + @SuppressWarnings("CheckReturnValue") public static class LimitCommandContext extends ParserRuleContext { public TerminalNode LIMIT() { return getToken(EsqlBaseParser.LIMIT, 0); } @@ -3399,13 +3494,13 @@ public class EsqlBaseParser extends Parser { public final LimitCommandContext limitCommand() throws RecognitionException { LimitCommandContext _localctx = new LimitCommandContext(_ctx, getState()); - enterRule(_localctx, 60, RULE_limitCommand); + enterRule(_localctx, 62, RULE_limitCommand); try { enterOuterAlt(_localctx, 1); { - setState(421); + setState(427); match(LIMIT); - setState(422); + setState(428); match(INTEGER_LITERAL); } } @@ -3455,32 +3550,32 @@ public class EsqlBaseParser extends Parser { public final SortCommandContext sortCommand() throws RecognitionException { SortCommandContext _localctx = new SortCommandContext(_ctx, getState()); - enterRule(_localctx, 62, RULE_sortCommand); + enterRule(_localctx, 64, RULE_sortCommand); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(424); - match(SORT); - setState(425); - orderExpression(); setState(430); + match(SORT); + setState(431); + orderExpression(); + setState(436); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,39,_ctx); + _alt = getInterpreter().adaptivePredict(_input,40,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(426); + setState(432); match(COMMA); - setState(427); + setState(433); orderExpression(); } } } - setState(432); + setState(438); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,39,_ctx); + _alt = getInterpreter().adaptivePredict(_input,40,_ctx); } } } @@ -3529,19 +3624,19 @@ public class EsqlBaseParser extends Parser { public final OrderExpressionContext orderExpression() throws RecognitionException { OrderExpressionContext _localctx = new OrderExpressionContext(_ctx, getState()); - enterRule(_localctx, 64, RULE_orderExpression); + enterRule(_localctx, 66, RULE_orderExpression); int _la; try { enterOuterAlt(_localctx, 1); { - setState(433); + setState(439); booleanExpression(0); - setState(435); + setState(441); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) { case 1: { - setState(434); + setState(440); ((OrderExpressionContext)_localctx).ordering = _input.LT(1); _la = _input.LA(1); if ( !(_la==ASC || _la==DESC) ) { @@ -3555,14 +3650,14 @@ public class EsqlBaseParser extends Parser { } break; } - setState(439); + setState(445); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) { case 1: { - setState(437); + setState(443); match(NULLS); - setState(438); + setState(444); ((OrderExpressionContext)_localctx).nullOrdering = _input.LT(1); _la = _input.LA(1); if ( !(_la==FIRST || _la==LAST) ) { @@ -3617,13 +3712,13 @@ public class EsqlBaseParser extends Parser { public final KeepCommandContext keepCommand() throws RecognitionException { KeepCommandContext _localctx = new KeepCommandContext(_ctx, getState()); - enterRule(_localctx, 66, RULE_keepCommand); + enterRule(_localctx, 68, RULE_keepCommand); try { enterOuterAlt(_localctx, 1); { - setState(441); + setState(447); match(KEEP); - setState(442); + setState(448); qualifiedNamePatterns(); } } @@ -3666,13 +3761,13 @@ public class EsqlBaseParser extends Parser { public final DropCommandContext dropCommand() throws RecognitionException { DropCommandContext _localctx = new DropCommandContext(_ctx, getState()); - enterRule(_localctx, 68, RULE_dropCommand); + enterRule(_localctx, 70, RULE_dropCommand); try { enterOuterAlt(_localctx, 1); { - setState(444); + setState(450); match(DROP); - setState(445); + setState(451); qualifiedNamePatterns(); } } @@ -3722,32 +3817,32 @@ public class EsqlBaseParser extends Parser { public final RenameCommandContext renameCommand() throws RecognitionException { RenameCommandContext _localctx = new RenameCommandContext(_ctx, getState()); - enterRule(_localctx, 70, RULE_renameCommand); + enterRule(_localctx, 72, RULE_renameCommand); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(447); - match(RENAME); - setState(448); - renameClause(); setState(453); + match(RENAME); + setState(454); + renameClause(); + setState(459); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,42,_ctx); + _alt = getInterpreter().adaptivePredict(_input,43,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(449); + setState(455); match(COMMA); - setState(450); + setState(456); renameClause(); } } } - setState(455); + setState(461); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,42,_ctx); + _alt = getInterpreter().adaptivePredict(_input,43,_ctx); } } } @@ -3795,15 +3890,15 @@ public class EsqlBaseParser extends Parser { public final RenameClauseContext renameClause() throws RecognitionException { RenameClauseContext _localctx = new RenameClauseContext(_ctx, getState()); - enterRule(_localctx, 72, RULE_renameClause); + enterRule(_localctx, 74, RULE_renameClause); try { enterOuterAlt(_localctx, 1); { - setState(456); + setState(462); ((RenameClauseContext)_localctx).oldName = qualifiedNamePattern(); - setState(457); + setState(463); match(AS); - setState(458); + setState(464); ((RenameClauseContext)_localctx).newName = qualifiedNamePattern(); } } @@ -3852,22 +3947,22 @@ public class EsqlBaseParser extends Parser { public final DissectCommandContext dissectCommand() throws RecognitionException { DissectCommandContext _localctx = new DissectCommandContext(_ctx, getState()); - enterRule(_localctx, 74, RULE_dissectCommand); + enterRule(_localctx, 76, RULE_dissectCommand); try { enterOuterAlt(_localctx, 1); { - setState(460); + setState(466); match(DISSECT); - setState(461); + setState(467); primaryExpression(0); - setState(462); + setState(468); string(); - setState(464); + setState(470); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,44,_ctx) ) { case 1: { - setState(463); + setState(469); commandOptions(); } break; @@ -3916,15 +4011,15 @@ public class EsqlBaseParser extends Parser { public final GrokCommandContext grokCommand() throws RecognitionException { GrokCommandContext _localctx = new GrokCommandContext(_ctx, getState()); - enterRule(_localctx, 76, RULE_grokCommand); + enterRule(_localctx, 78, RULE_grokCommand); try { enterOuterAlt(_localctx, 1); { - setState(466); + setState(472); match(GROK); - setState(467); + setState(473); primaryExpression(0); - setState(468); + setState(474); string(); } } @@ -3967,13 +4062,13 @@ public class EsqlBaseParser extends Parser { public final MvExpandCommandContext mvExpandCommand() throws RecognitionException { MvExpandCommandContext _localctx = new MvExpandCommandContext(_ctx, getState()); - enterRule(_localctx, 78, RULE_mvExpandCommand); + enterRule(_localctx, 80, RULE_mvExpandCommand); try { enterOuterAlt(_localctx, 1); { - setState(470); + setState(476); match(MV_EXPAND); - setState(471); + setState(477); qualifiedName(); } } @@ -4022,30 +4117,30 @@ public class EsqlBaseParser extends Parser { public final CommandOptionsContext commandOptions() throws RecognitionException { CommandOptionsContext _localctx = new CommandOptionsContext(_ctx, getState()); - enterRule(_localctx, 80, RULE_commandOptions); + enterRule(_localctx, 82, RULE_commandOptions); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(473); + setState(479); commandOption(); - setState(478); + setState(484); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,44,_ctx); + _alt = getInterpreter().adaptivePredict(_input,45,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(474); + setState(480); match(COMMA); - setState(475); + setState(481); commandOption(); } } } - setState(480); + setState(486); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,44,_ctx); + _alt = getInterpreter().adaptivePredict(_input,45,_ctx); } } } @@ -4091,15 +4186,15 @@ public class EsqlBaseParser extends Parser { public final CommandOptionContext commandOption() throws RecognitionException { CommandOptionContext _localctx = new CommandOptionContext(_ctx, getState()); - enterRule(_localctx, 82, RULE_commandOption); + enterRule(_localctx, 84, RULE_commandOption); try { enterOuterAlt(_localctx, 1); { - setState(481); + setState(487); identifier(); - setState(482); + setState(488); match(ASSIGN); - setState(483); + setState(489); constant(); } } @@ -4140,12 +4235,12 @@ public class EsqlBaseParser extends Parser { public final BooleanValueContext booleanValue() throws RecognitionException { BooleanValueContext _localctx = new BooleanValueContext(_ctx, getState()); - enterRule(_localctx, 84, RULE_booleanValue); + enterRule(_localctx, 86, RULE_booleanValue); int _la; try { enterOuterAlt(_localctx, 1); { - setState(485); + setState(491); _la = _input.LA(1); if ( !(_la==FALSE || _la==TRUE) ) { _errHandler.recoverInline(this); @@ -4198,22 +4293,22 @@ public class EsqlBaseParser extends Parser { public final NumericValueContext numericValue() throws RecognitionException { NumericValueContext _localctx = new NumericValueContext(_ctx, getState()); - enterRule(_localctx, 86, RULE_numericValue); + enterRule(_localctx, 88, RULE_numericValue); try { - setState(489); + setState(495); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,45,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,46,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(487); + setState(493); decimalValue(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(488); + setState(494); integerValue(); } break; @@ -4257,17 +4352,17 @@ public class EsqlBaseParser extends Parser { public final DecimalValueContext decimalValue() throws RecognitionException { DecimalValueContext _localctx = new DecimalValueContext(_ctx, getState()); - enterRule(_localctx, 88, RULE_decimalValue); + enterRule(_localctx, 90, RULE_decimalValue); int _la; try { enterOuterAlt(_localctx, 1); { - setState(492); + setState(498); _errHandler.sync(this); _la = _input.LA(1); if (_la==PLUS || _la==MINUS) { { - setState(491); + setState(497); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { _errHandler.recoverInline(this); @@ -4280,7 +4375,7 @@ public class EsqlBaseParser extends Parser { } } - setState(494); + setState(500); match(DECIMAL_LITERAL); } } @@ -4322,17 +4417,17 @@ public class EsqlBaseParser extends Parser { public final IntegerValueContext integerValue() throws RecognitionException { IntegerValueContext _localctx = new IntegerValueContext(_ctx, getState()); - enterRule(_localctx, 90, RULE_integerValue); + enterRule(_localctx, 92, RULE_integerValue); int _la; try { enterOuterAlt(_localctx, 1); { - setState(497); + setState(503); _errHandler.sync(this); _la = _input.LA(1); if (_la==PLUS || _la==MINUS) { { - setState(496); + setState(502); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { _errHandler.recoverInline(this); @@ -4345,7 +4440,7 @@ public class EsqlBaseParser extends Parser { } } - setState(499); + setState(505); match(INTEGER_LITERAL); } } @@ -4385,11 +4480,11 @@ public class EsqlBaseParser extends Parser { public final StringContext string() throws RecognitionException { StringContext _localctx = new StringContext(_ctx, getState()); - enterRule(_localctx, 92, RULE_string); + enterRule(_localctx, 94, RULE_string); try { enterOuterAlt(_localctx, 1); { - setState(501); + setState(507); match(QUOTED_STRING); } } @@ -4434,12 +4529,12 @@ public class EsqlBaseParser extends Parser { public final ComparisonOperatorContext comparisonOperator() throws RecognitionException { ComparisonOperatorContext _localctx = new ComparisonOperatorContext(_ctx, getState()); - enterRule(_localctx, 94, RULE_comparisonOperator); + enterRule(_localctx, 96, RULE_comparisonOperator); int _la; try { enterOuterAlt(_localctx, 1); { - setState(503); + setState(509); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 9007199254740992000L) != 0)) ) { _errHandler.recoverInline(this); @@ -4490,13 +4585,13 @@ public class EsqlBaseParser extends Parser { public final ExplainCommandContext explainCommand() throws RecognitionException { ExplainCommandContext _localctx = new ExplainCommandContext(_ctx, getState()); - enterRule(_localctx, 96, RULE_explainCommand); + enterRule(_localctx, 98, RULE_explainCommand); try { enterOuterAlt(_localctx, 1); { - setState(505); + setState(511); match(EXPLAIN); - setState(506); + setState(512); subqueryExpression(); } } @@ -4540,15 +4635,15 @@ public class EsqlBaseParser extends Parser { public final SubqueryExpressionContext subqueryExpression() throws RecognitionException { SubqueryExpressionContext _localctx = new SubqueryExpressionContext(_ctx, getState()); - enterRule(_localctx, 98, RULE_subqueryExpression); + enterRule(_localctx, 100, RULE_subqueryExpression); try { enterOuterAlt(_localctx, 1); { - setState(508); + setState(514); match(OPENING_BRACKET); - setState(509); + setState(515); query(0); - setState(510); + setState(516); match(CLOSING_BRACKET); } } @@ -4600,14 +4695,14 @@ public class EsqlBaseParser extends Parser { public final ShowCommandContext showCommand() throws RecognitionException { ShowCommandContext _localctx = new ShowCommandContext(_ctx, getState()); - enterRule(_localctx, 100, RULE_showCommand); + enterRule(_localctx, 102, RULE_showCommand); try { _localctx = new ShowInfoContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(512); + setState(518); match(SHOW); - setState(513); + setState(519); match(INFO); } } @@ -4659,14 +4754,14 @@ public class EsqlBaseParser extends Parser { public final MetaCommandContext metaCommand() throws RecognitionException { MetaCommandContext _localctx = new MetaCommandContext(_ctx, getState()); - enterRule(_localctx, 102, RULE_metaCommand); + enterRule(_localctx, 104, RULE_metaCommand); try { _localctx = new MetaFunctionsContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(515); + setState(521); match(META); - setState(516); + setState(522); match(FUNCTIONS); } } @@ -4724,53 +4819,53 @@ public class EsqlBaseParser extends Parser { public final EnrichCommandContext enrichCommand() throws RecognitionException { EnrichCommandContext _localctx = new EnrichCommandContext(_ctx, getState()); - enterRule(_localctx, 104, RULE_enrichCommand); + enterRule(_localctx, 106, RULE_enrichCommand); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(518); + setState(524); match(ENRICH); - setState(519); + setState(525); ((EnrichCommandContext)_localctx).policyName = match(ENRICH_POLICY_NAME); - setState(522); + setState(528); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,48,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) { case 1: { - setState(520); + setState(526); match(ON); - setState(521); + setState(527); ((EnrichCommandContext)_localctx).matchField = qualifiedNamePattern(); } break; } - setState(533); + setState(539); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,50,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) { case 1: { - setState(524); - match(WITH); - setState(525); - enrichWithClause(); setState(530); + match(WITH); + setState(531); + enrichWithClause(); + setState(536); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,49,_ctx); + _alt = getInterpreter().adaptivePredict(_input,50,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(526); + setState(532); match(COMMA); - setState(527); + setState(533); enrichWithClause(); } } } - setState(532); + setState(538); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,49,_ctx); + _alt = getInterpreter().adaptivePredict(_input,50,_ctx); } } break; @@ -4821,23 +4916,23 @@ public class EsqlBaseParser extends Parser { public final EnrichWithClauseContext enrichWithClause() throws RecognitionException { EnrichWithClauseContext _localctx = new EnrichWithClauseContext(_ctx, getState()); - enterRule(_localctx, 106, RULE_enrichWithClause); + enterRule(_localctx, 108, RULE_enrichWithClause); try { enterOuterAlt(_localctx, 1); { - setState(538); + setState(544); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,52,_ctx) ) { case 1: { - setState(535); + setState(541); ((EnrichWithClauseContext)_localctx).newName = qualifiedNamePattern(); - setState(536); + setState(542); match(ASSIGN); } break; } - setState(540); + setState(546); ((EnrichWithClauseContext)_localctx).enrichField = qualifiedNamePattern(); } } @@ -4884,17 +4979,17 @@ public class EsqlBaseParser extends Parser { public final LookupCommandContext lookupCommand() throws RecognitionException { LookupCommandContext _localctx = new LookupCommandContext(_ctx, getState()); - enterRule(_localctx, 108, RULE_lookupCommand); + enterRule(_localctx, 110, RULE_lookupCommand); try { enterOuterAlt(_localctx, 1); { - setState(542); + setState(548); match(LOOKUP); - setState(543); + setState(549); ((LookupCommandContext)_localctx).tableName = match(INDEX_UNQUOTED_IDENTIFIER); - setState(544); + setState(550); match(ON); - setState(545); + setState(551); ((LookupCommandContext)_localctx).matchFields = qualifiedNamePatterns(); } } @@ -4956,7 +5051,7 @@ public class EsqlBaseParser extends Parser { } public static final String _serializedATN = - "\u0004\u0001{\u0224\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0004\u0001|\u022a\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ @@ -4970,341 +5065,344 @@ public class EsqlBaseParser extends Parser { "#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007&\u0002\'\u0007\'\u0002"+ "(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002"+ "-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u00070\u00021\u00071\u0002"+ - "2\u00072\u00023\u00073\u00024\u00074\u00025\u00075\u00026\u00076\u0001"+ - "\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0001\u0005\u0001x\b\u0001\n\u0001\f\u0001{\t"+ - "\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+ - "\u0002\u0003\u0002\u0083\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+ + "2\u00072\u00023\u00073\u00024\u00074\u00025\u00075\u00026\u00076\u0002"+ + "7\u00077\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001z\b\u0001\n\u0001"+ + "\f\u0001}\t\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+ + "\u0002\u0001\u0002\u0003\u0002\u0085\b\u0002\u0001\u0003\u0001\u0003\u0001"+ "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+ - "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003\u0003\u0093"+ - "\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001"+ - "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u009f"+ - "\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0005"+ - "\u0005\u00a6\b\u0005\n\u0005\f\u0005\u00a9\t\u0005\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00b0\b\u0005\u0001\u0005"+ - "\u0001\u0005\u0003\u0005\u00b4\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0005\u0001\u0005\u0005\u0005\u00bc\b\u0005\n\u0005"+ - "\f\u0005\u00bf\t\u0005\u0001\u0006\u0001\u0006\u0003\u0006\u00c3\b\u0006"+ - "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0003\u0006"+ - "\u00ca\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0003\u0006\u00cf\b"+ - "\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0003"+ - "\u0007\u00d6\b\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0003\b\u00dc\b\b"+ - "\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0005\b\u00e4\b\b\n\b"+ - "\f\b\u00e7\t\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t"+ - "\u0001\t\u0003\t\u00f1\b\t\u0001\t\u0001\t\u0001\t\u0005\t\u00f6\b\t\n"+ - "\t\f\t\u00f9\t\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0005"+ - "\n\u0101\b\n\n\n\f\n\u0104\t\n\u0003\n\u0106\b\n\u0001\n\u0001\n\u0001"+ + "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003"+ + "\u0003\u0095\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003"+ + "\u0005\u00a1\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0005\u0005\u00a8\b\u0005\n\u0005\f\u0005\u00ab\t\u0005\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00b2\b\u0005"+ + "\u0001\u0005\u0001\u0005\u0003\u0005\u00b6\b\u0005\u0001\u0005\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0005\u0005\u00be\b\u0005"+ + "\n\u0005\f\u0005\u00c1\t\u0005\u0001\u0006\u0001\u0006\u0003\u0006\u00c5"+ + "\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0003"+ + "\u0006\u00cc\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0003\u0006\u00d1"+ + "\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0003"+ + "\u0007\u00d8\b\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0003\b\u00de\b\b"+ + "\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0005\b\u00e6\b\b\n\b"+ + "\f\b\u00e9\t\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t"+ + "\u0001\t\u0003\t\u00f3\b\t\u0001\t\u0001\t\u0001\t\u0005\t\u00f8\b\t\n"+ + "\t\f\t\u00fb\t\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0005"+ + "\n\u0103\b\n\n\n\f\n\u0106\t\n\u0003\n\u0108\b\n\u0001\n\u0001\n\u0001"+ "\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0005"+ - "\r\u0112\b\r\n\r\f\r\u0115\t\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ - "\u000e\u0001\u000e\u0003\u000e\u011c\b\u000e\u0001\u000f\u0001\u000f\u0001"+ - "\u000f\u0001\u000f\u0005\u000f\u0122\b\u000f\n\u000f\f\u000f\u0125\t\u000f"+ - "\u0001\u000f\u0003\u000f\u0128\b\u000f\u0001\u0010\u0001\u0010\u0001\u0011"+ - "\u0001\u0011\u0003\u0011\u012e\b\u0011\u0001\u0012\u0001\u0012\u0001\u0012"+ - "\u0001\u0012\u0005\u0012\u0134\b\u0012\n\u0012\f\u0012\u0137\t\u0012\u0001"+ + "\r\u0114\b\r\n\r\f\r\u0117\t\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0003\u000e\u011e\b\u000e\u0001\u000f\u0001\u000f\u0001"+ + "\u000f\u0001\u000f\u0005\u000f\u0124\b\u000f\n\u000f\f\u000f\u0127\t\u000f"+ + "\u0001\u000f\u0003\u000f\u012a\b\u000f\u0001\u0010\u0001\u0010\u0001\u0011"+ + "\u0001\u0011\u0003\u0011\u0130\b\u0011\u0001\u0012\u0001\u0012\u0001\u0012"+ + "\u0001\u0012\u0005\u0012\u0136\b\u0012\n\u0012\f\u0012\u0139\t\u0012\u0001"+ "\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001"+ - "\u0014\u0001\u0014\u0005\u0014\u0141\b\u0014\n\u0014\f\u0014\u0144\t\u0014"+ - "\u0001\u0014\u0003\u0014\u0147\b\u0014\u0001\u0014\u0001\u0014\u0003\u0014"+ - "\u014b\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016"+ - "\u0003\u0016\u0152\b\u0016\u0001\u0016\u0001\u0016\u0003\u0016\u0156\b"+ - "\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0003\u0017\u015c"+ - "\b\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0005\u0018\u0161\b\u0018"+ - "\n\u0018\f\u0018\u0164\t\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0005"+ - "\u0019\u0169\b\u0019\n\u0019\f\u0019\u016c\t\u0019\u0001\u001a\u0001\u001a"+ - "\u0001\u001a\u0005\u001a\u0171\b\u001a\n\u001a\f\u001a\u0174\t\u001a\u0001"+ + "\u0014\u0001\u0014\u0005\u0014\u0143\b\u0014\n\u0014\f\u0014\u0146\t\u0014"+ + "\u0001\u0014\u0003\u0014\u0149\b\u0014\u0001\u0014\u0001\u0014\u0003\u0014"+ + "\u014d\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016"+ + "\u0003\u0016\u0154\b\u0016\u0001\u0016\u0001\u0016\u0003\u0016\u0158\b"+ + "\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0003\u0017\u015e"+ + "\b\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0005\u0018\u0163\b\u0018"+ + "\n\u0018\f\u0018\u0166\t\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0005"+ + "\u0019\u016b\b\u0019\n\u0019\f\u0019\u016e\t\u0019\u0001\u001a\u0001\u001a"+ + "\u0001\u001a\u0005\u001a\u0173\b\u001a\n\u001a\f\u001a\u0176\t\u001a\u0001"+ "\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001"+ "\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001"+ - "\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0005\u001d\u0187"+ - "\b\u001d\n\u001d\f\u001d\u018a\t\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ - "\u0001\u001d\u0001\u001d\u0001\u001d\u0005\u001d\u0192\b\u001d\n\u001d"+ - "\f\u001d\u0195\t\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ - "\u0001\u001d\u0001\u001d\u0005\u001d\u019d\b\u001d\n\u001d\f\u001d\u01a0"+ - "\t\u001d\u0001\u001d\u0001\u001d\u0003\u001d\u01a4\b\u001d\u0001\u001e"+ - "\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f"+ - "\u0005\u001f\u01ad\b\u001f\n\u001f\f\u001f\u01b0\t\u001f\u0001 \u0001"+ - " \u0003 \u01b4\b \u0001 \u0001 \u0003 \u01b8\b \u0001!\u0001!\u0001!\u0001"+ - "\"\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0001#\u0005#\u01c4\b#\n#\f#\u01c7"+ - "\t#\u0001$\u0001$\u0001$\u0001$\u0001%\u0001%\u0001%\u0001%\u0003%\u01d1"+ - "\b%\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001(\u0001("+ - "\u0001(\u0005(\u01dd\b(\n(\f(\u01e0\t(\u0001)\u0001)\u0001)\u0001)\u0001"+ - "*\u0001*\u0001+\u0001+\u0003+\u01ea\b+\u0001,\u0003,\u01ed\b,\u0001,\u0001"+ - ",\u0001-\u0003-\u01f2\b-\u0001-\u0001-\u0001.\u0001.\u0001/\u0001/\u0001"+ - "0\u00010\u00010\u00011\u00011\u00011\u00011\u00012\u00012\u00012\u0001"+ - "3\u00013\u00013\u00014\u00014\u00014\u00014\u00034\u020b\b4\u00014\u0001"+ - "4\u00014\u00014\u00054\u0211\b4\n4\f4\u0214\t4\u00034\u0216\b4\u00015"+ - "\u00015\u00015\u00035\u021b\b5\u00015\u00015\u00016\u00016\u00016\u0001"+ - "6\u00016\u00016\u0000\u0004\u0002\n\u0010\u00127\u0000\u0002\u0004\u0006"+ - "\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,."+ - "02468:<>@BDFHJLNPRTVXZ\\^`bdfhjl\u0000\u0007\u0001\u0000?@\u0001\u0000"+ - "AC\u0001\u0000FG\u0002\u0000##\'\'\u0001\u0000*+\u0002\u0000))77\u0002"+ - "\u000088:>\u023e\u0000n\u0001\u0000\u0000\u0000\u0002q\u0001\u0000\u0000"+ - "\u0000\u0004\u0082\u0001\u0000\u0000\u0000\u0006\u0092\u0001\u0000\u0000"+ - "\u0000\b\u0094\u0001\u0000\u0000\u0000\n\u00b3\u0001\u0000\u0000\u0000"+ - "\f\u00ce\u0001\u0000\u0000\u0000\u000e\u00d5\u0001\u0000\u0000\u0000\u0010"+ - "\u00db\u0001\u0000\u0000\u0000\u0012\u00f0\u0001\u0000\u0000\u0000\u0014"+ - "\u00fa\u0001\u0000\u0000\u0000\u0016\u0109\u0001\u0000\u0000\u0000\u0018"+ - "\u010b\u0001\u0000\u0000\u0000\u001a\u010e\u0001\u0000\u0000\u0000\u001c"+ - "\u011b\u0001\u0000\u0000\u0000\u001e\u011d\u0001\u0000\u0000\u0000 \u0129"+ - "\u0001\u0000\u0000\u0000\"\u012d\u0001\u0000\u0000\u0000$\u012f\u0001"+ - "\u0000\u0000\u0000&\u0138\u0001\u0000\u0000\u0000(\u013c\u0001\u0000\u0000"+ - "\u0000*\u014c\u0001\u0000\u0000\u0000,\u014f\u0001\u0000\u0000\u0000."+ - "\u0157\u0001\u0000\u0000\u00000\u015d\u0001\u0000\u0000\u00002\u0165\u0001"+ - "\u0000\u0000\u00004\u016d\u0001\u0000\u0000\u00006\u0175\u0001\u0000\u0000"+ - "\u00008\u0177\u0001\u0000\u0000\u0000:\u01a3\u0001\u0000\u0000\u0000<"+ - "\u01a5\u0001\u0000\u0000\u0000>\u01a8\u0001\u0000\u0000\u0000@\u01b1\u0001"+ - "\u0000\u0000\u0000B\u01b9\u0001\u0000\u0000\u0000D\u01bc\u0001\u0000\u0000"+ - "\u0000F\u01bf\u0001\u0000\u0000\u0000H\u01c8\u0001\u0000\u0000\u0000J"+ - "\u01cc\u0001\u0000\u0000\u0000L\u01d2\u0001\u0000\u0000\u0000N\u01d6\u0001"+ - "\u0000\u0000\u0000P\u01d9\u0001\u0000\u0000\u0000R\u01e1\u0001\u0000\u0000"+ - "\u0000T\u01e5\u0001\u0000\u0000\u0000V\u01e9\u0001\u0000\u0000\u0000X"+ - "\u01ec\u0001\u0000\u0000\u0000Z\u01f1\u0001\u0000\u0000\u0000\\\u01f5"+ - "\u0001\u0000\u0000\u0000^\u01f7\u0001\u0000\u0000\u0000`\u01f9\u0001\u0000"+ - "\u0000\u0000b\u01fc\u0001\u0000\u0000\u0000d\u0200\u0001\u0000\u0000\u0000"+ - "f\u0203\u0001\u0000\u0000\u0000h\u0206\u0001\u0000\u0000\u0000j\u021a"+ - "\u0001\u0000\u0000\u0000l\u021e\u0001\u0000\u0000\u0000no\u0003\u0002"+ - "\u0001\u0000op\u0005\u0000\u0000\u0001p\u0001\u0001\u0000\u0000\u0000"+ - "qr\u0006\u0001\uffff\uffff\u0000rs\u0003\u0004\u0002\u0000sy\u0001\u0000"+ - "\u0000\u0000tu\n\u0001\u0000\u0000uv\u0005\u001d\u0000\u0000vx\u0003\u0006"+ - "\u0003\u0000wt\u0001\u0000\u0000\u0000x{\u0001\u0000\u0000\u0000yw\u0001"+ - "\u0000\u0000\u0000yz\u0001\u0000\u0000\u0000z\u0003\u0001\u0000\u0000"+ - "\u0000{y\u0001\u0000\u0000\u0000|\u0083\u0003`0\u0000}\u0083\u0003\u001e"+ - "\u000f\u0000~\u0083\u0003\u0018\f\u0000\u007f\u0083\u0003(\u0014\u0000"+ - "\u0080\u0083\u0003d2\u0000\u0081\u0083\u0003f3\u0000\u0082|\u0001\u0000"+ - "\u0000\u0000\u0082}\u0001\u0000\u0000\u0000\u0082~\u0001\u0000\u0000\u0000"+ - "\u0082\u007f\u0001\u0000\u0000\u0000\u0082\u0080\u0001\u0000\u0000\u0000"+ - "\u0082\u0081\u0001\u0000\u0000\u0000\u0083\u0005\u0001\u0000\u0000\u0000"+ - "\u0084\u0093\u0003*\u0015\u0000\u0085\u0093\u0003.\u0017\u0000\u0086\u0093"+ - "\u0003<\u001e\u0000\u0087\u0093\u0003l6\u0000\u0088\u0093\u0003B!\u0000"+ - "\u0089\u0093\u0003>\u001f\u0000\u008a\u0093\u0003,\u0016\u0000\u008b\u0093"+ - "\u0003\b\u0004\u0000\u008c\u0093\u0003D\"\u0000\u008d\u0093\u0003F#\u0000"+ - "\u008e\u0093\u0003J%\u0000\u008f\u0093\u0003L&\u0000\u0090\u0093\u0003"+ - "h4\u0000\u0091\u0093\u0003N\'\u0000\u0092\u0084\u0001\u0000\u0000\u0000"+ - "\u0092\u0085\u0001\u0000\u0000\u0000\u0092\u0086\u0001\u0000\u0000\u0000"+ - "\u0092\u0087\u0001\u0000\u0000\u0000\u0092\u0088\u0001\u0000\u0000\u0000"+ - "\u0092\u0089\u0001\u0000\u0000\u0000\u0092\u008a\u0001\u0000\u0000\u0000"+ - "\u0092\u008b\u0001\u0000\u0000\u0000\u0092\u008c\u0001\u0000\u0000\u0000"+ - "\u0092\u008d\u0001\u0000\u0000\u0000\u0092\u008e\u0001\u0000\u0000\u0000"+ - "\u0092\u008f\u0001\u0000\u0000\u0000\u0092\u0090\u0001\u0000\u0000\u0000"+ - "\u0092\u0091\u0001\u0000\u0000\u0000\u0093\u0007\u0001\u0000\u0000\u0000"+ - "\u0094\u0095\u0005\u0014\u0000\u0000\u0095\u0096\u0003\n\u0005\u0000\u0096"+ - "\t\u0001\u0000\u0000\u0000\u0097\u0098\u0006\u0005\uffff\uffff\u0000\u0098"+ - "\u0099\u00050\u0000\u0000\u0099\u00b4\u0003\n\u0005\u0007\u009a\u00b4"+ - "\u0003\u000e\u0007\u0000\u009b\u00b4\u0003\f\u0006\u0000\u009c\u009e\u0003"+ - "\u000e\u0007\u0000\u009d\u009f\u00050\u0000\u0000\u009e\u009d\u0001\u0000"+ - "\u0000\u0000\u009e\u009f\u0001\u0000\u0000\u0000\u009f\u00a0\u0001\u0000"+ - "\u0000\u0000\u00a0\u00a1\u0005-\u0000\u0000\u00a1\u00a2\u0005,\u0000\u0000"+ - "\u00a2\u00a7\u0003\u000e\u0007\u0000\u00a3\u00a4\u0005&\u0000\u0000\u00a4"+ - "\u00a6\u0003\u000e\u0007\u0000\u00a5\u00a3\u0001\u0000\u0000\u0000\u00a6"+ - "\u00a9\u0001\u0000\u0000\u0000\u00a7\u00a5\u0001\u0000\u0000\u0000\u00a7"+ - "\u00a8\u0001\u0000\u0000\u0000\u00a8\u00aa\u0001\u0000\u0000\u0000\u00a9"+ - "\u00a7\u0001\u0000\u0000\u0000\u00aa\u00ab\u00056\u0000\u0000\u00ab\u00b4"+ - "\u0001\u0000\u0000\u0000\u00ac\u00ad\u0003\u000e\u0007\u0000\u00ad\u00af"+ - "\u0005.\u0000\u0000\u00ae\u00b0\u00050\u0000\u0000\u00af\u00ae\u0001\u0000"+ - "\u0000\u0000\u00af\u00b0\u0001\u0000\u0000\u0000\u00b0\u00b1\u0001\u0000"+ - "\u0000\u0000\u00b1\u00b2\u00051\u0000\u0000\u00b2\u00b4\u0001\u0000\u0000"+ - "\u0000\u00b3\u0097\u0001\u0000\u0000\u0000\u00b3\u009a\u0001\u0000\u0000"+ - "\u0000\u00b3\u009b\u0001\u0000\u0000\u0000\u00b3\u009c\u0001\u0000\u0000"+ - "\u0000\u00b3\u00ac\u0001\u0000\u0000\u0000\u00b4\u00bd\u0001\u0000\u0000"+ - "\u0000\u00b5\u00b6\n\u0004\u0000\u0000\u00b6\u00b7\u0005\"\u0000\u0000"+ - "\u00b7\u00bc\u0003\n\u0005\u0005\u00b8\u00b9\n\u0003\u0000\u0000\u00b9"+ - "\u00ba\u00053\u0000\u0000\u00ba\u00bc\u0003\n\u0005\u0004\u00bb\u00b5"+ - "\u0001\u0000\u0000\u0000\u00bb\u00b8\u0001\u0000\u0000\u0000\u00bc\u00bf"+ - "\u0001\u0000\u0000\u0000\u00bd\u00bb\u0001\u0000\u0000\u0000\u00bd\u00be"+ - "\u0001\u0000\u0000\u0000\u00be\u000b\u0001\u0000\u0000\u0000\u00bf\u00bd"+ - "\u0001\u0000\u0000\u0000\u00c0\u00c2\u0003\u000e\u0007\u0000\u00c1\u00c3"+ - "\u00050\u0000\u0000\u00c2\u00c1\u0001\u0000\u0000\u0000\u00c2\u00c3\u0001"+ - "\u0000\u0000\u0000\u00c3\u00c4\u0001\u0000\u0000\u0000\u00c4\u00c5\u0005"+ - "/\u0000\u0000\u00c5\u00c6\u0003\\.\u0000\u00c6\u00cf\u0001\u0000\u0000"+ - "\u0000\u00c7\u00c9\u0003\u000e\u0007\u0000\u00c8\u00ca\u00050\u0000\u0000"+ - "\u00c9\u00c8\u0001\u0000\u0000\u0000\u00c9\u00ca\u0001\u0000\u0000\u0000"+ - "\u00ca\u00cb\u0001\u0000\u0000\u0000\u00cb\u00cc\u00055\u0000\u0000\u00cc"+ - "\u00cd\u0003\\.\u0000\u00cd\u00cf\u0001\u0000\u0000\u0000\u00ce\u00c0"+ - "\u0001\u0000\u0000\u0000\u00ce\u00c7\u0001\u0000\u0000\u0000\u00cf\r\u0001"+ - "\u0000\u0000\u0000\u00d0\u00d6\u0003\u0010\b\u0000\u00d1\u00d2\u0003\u0010"+ - "\b\u0000\u00d2\u00d3\u0003^/\u0000\u00d3\u00d4\u0003\u0010\b\u0000\u00d4"+ - "\u00d6\u0001\u0000\u0000\u0000\u00d5\u00d0\u0001\u0000\u0000\u0000\u00d5"+ - "\u00d1\u0001\u0000\u0000\u0000\u00d6\u000f\u0001\u0000\u0000\u0000\u00d7"+ - "\u00d8\u0006\b\uffff\uffff\u0000\u00d8\u00dc\u0003\u0012\t\u0000\u00d9"+ - "\u00da\u0007\u0000\u0000\u0000\u00da\u00dc\u0003\u0010\b\u0003\u00db\u00d7"+ - "\u0001\u0000\u0000\u0000\u00db\u00d9\u0001\u0000\u0000\u0000\u00dc\u00e5"+ - "\u0001\u0000\u0000\u0000\u00dd\u00de\n\u0002\u0000\u0000\u00de\u00df\u0007"+ - "\u0001\u0000\u0000\u00df\u00e4\u0003\u0010\b\u0003\u00e0\u00e1\n\u0001"+ - "\u0000\u0000\u00e1\u00e2\u0007\u0000\u0000\u0000\u00e2\u00e4\u0003\u0010"+ - "\b\u0002\u00e3\u00dd\u0001\u0000\u0000\u0000\u00e3\u00e0\u0001\u0000\u0000"+ - "\u0000\u00e4\u00e7\u0001\u0000\u0000\u0000\u00e5\u00e3\u0001\u0000\u0000"+ - "\u0000\u00e5\u00e6\u0001\u0000\u0000\u0000\u00e6\u0011\u0001\u0000\u0000"+ - "\u0000\u00e7\u00e5\u0001\u0000\u0000\u0000\u00e8\u00e9\u0006\t\uffff\uffff"+ - "\u0000\u00e9\u00f1\u0003:\u001d\u0000\u00ea\u00f1\u00030\u0018\u0000\u00eb"+ - "\u00f1\u0003\u0014\n\u0000\u00ec\u00ed\u0005,\u0000\u0000\u00ed\u00ee"+ - "\u0003\n\u0005\u0000\u00ee\u00ef\u00056\u0000\u0000\u00ef\u00f1\u0001"+ - "\u0000\u0000\u0000\u00f0\u00e8\u0001\u0000\u0000\u0000\u00f0\u00ea\u0001"+ - "\u0000\u0000\u0000\u00f0\u00eb\u0001\u0000\u0000\u0000\u00f0\u00ec\u0001"+ - "\u0000\u0000\u0000\u00f1\u00f7\u0001\u0000\u0000\u0000\u00f2\u00f3\n\u0001"+ - "\u0000\u0000\u00f3\u00f4\u0005%\u0000\u0000\u00f4\u00f6\u0003\u0016\u000b"+ - "\u0000\u00f5\u00f2\u0001\u0000\u0000\u0000\u00f6\u00f9\u0001\u0000\u0000"+ - "\u0000\u00f7\u00f5\u0001\u0000\u0000\u0000\u00f7\u00f8\u0001\u0000\u0000"+ - "\u0000\u00f8\u0013\u0001\u0000\u0000\u0000\u00f9\u00f7\u0001\u0000\u0000"+ - "\u0000\u00fa\u00fb\u00036\u001b\u0000\u00fb\u0105\u0005,\u0000\u0000\u00fc"+ - "\u0106\u0005A\u0000\u0000\u00fd\u0102\u0003\n\u0005\u0000\u00fe\u00ff"+ - "\u0005&\u0000\u0000\u00ff\u0101\u0003\n\u0005\u0000\u0100\u00fe\u0001"+ - "\u0000\u0000\u0000\u0101\u0104\u0001\u0000\u0000\u0000\u0102\u0100\u0001"+ - "\u0000\u0000\u0000\u0102\u0103\u0001\u0000\u0000\u0000\u0103\u0106\u0001"+ - "\u0000\u0000\u0000\u0104\u0102\u0001\u0000\u0000\u0000\u0105\u00fc\u0001"+ - "\u0000\u0000\u0000\u0105\u00fd\u0001\u0000\u0000\u0000\u0105\u0106\u0001"+ - "\u0000\u0000\u0000\u0106\u0107\u0001\u0000\u0000\u0000\u0107\u0108\u0005"+ - "6\u0000\u0000\u0108\u0015\u0001\u0000\u0000\u0000\u0109\u010a\u00036\u001b"+ - "\u0000\u010a\u0017\u0001\u0000\u0000\u0000\u010b\u010c\u0005\u0010\u0000"+ - "\u0000\u010c\u010d\u0003\u001a\r\u0000\u010d\u0019\u0001\u0000\u0000\u0000"+ - "\u010e\u0113\u0003\u001c\u000e\u0000\u010f\u0110\u0005&\u0000\u0000\u0110"+ - "\u0112\u0003\u001c\u000e\u0000\u0111\u010f\u0001\u0000\u0000\u0000\u0112"+ - "\u0115\u0001\u0000\u0000\u0000\u0113\u0111\u0001\u0000\u0000\u0000\u0113"+ - "\u0114\u0001\u0000\u0000\u0000\u0114\u001b\u0001\u0000\u0000\u0000\u0115"+ - "\u0113\u0001\u0000\u0000\u0000\u0116\u011c\u0003\n\u0005\u0000\u0117\u0118"+ - "\u00030\u0018\u0000\u0118\u0119\u0005$\u0000\u0000\u0119\u011a\u0003\n"+ - "\u0005\u0000\u011a\u011c\u0001\u0000\u0000\u0000\u011b\u0116\u0001\u0000"+ - "\u0000\u0000\u011b\u0117\u0001\u0000\u0000\u0000\u011c\u001d\u0001\u0000"+ - "\u0000\u0000\u011d\u011e\u0005\u0006\u0000\u0000\u011e\u0123\u0003 \u0010"+ - "\u0000\u011f\u0120\u0005&\u0000\u0000\u0120\u0122\u0003 \u0010\u0000\u0121"+ - "\u011f\u0001\u0000\u0000\u0000\u0122\u0125\u0001\u0000\u0000\u0000\u0123"+ - "\u0121\u0001\u0000\u0000\u0000\u0123\u0124\u0001\u0000\u0000\u0000\u0124"+ - "\u0127\u0001\u0000\u0000\u0000\u0125\u0123\u0001\u0000\u0000\u0000\u0126"+ - "\u0128\u0003\"\u0011\u0000\u0127\u0126\u0001\u0000\u0000\u0000\u0127\u0128"+ - "\u0001\u0000\u0000\u0000\u0128\u001f\u0001\u0000\u0000\u0000\u0129\u012a"+ - "\u0005\u0019\u0000\u0000\u012a!\u0001\u0000\u0000\u0000\u012b\u012e\u0003"+ - "$\u0012\u0000\u012c\u012e\u0003&\u0013\u0000\u012d\u012b\u0001\u0000\u0000"+ - "\u0000\u012d\u012c\u0001\u0000\u0000\u0000\u012e#\u0001\u0000\u0000\u0000"+ - "\u012f\u0130\u0005K\u0000\u0000\u0130\u0135\u0003 \u0010\u0000\u0131\u0132"+ - "\u0005&\u0000\u0000\u0132\u0134\u0003 \u0010\u0000\u0133\u0131\u0001\u0000"+ - "\u0000\u0000\u0134\u0137\u0001\u0000\u0000\u0000\u0135\u0133\u0001\u0000"+ - "\u0000\u0000\u0135\u0136\u0001\u0000\u0000\u0000\u0136%\u0001\u0000\u0000"+ - "\u0000\u0137\u0135\u0001\u0000\u0000\u0000\u0138\u0139\u0005D\u0000\u0000"+ - "\u0139\u013a\u0003$\u0012\u0000\u013a\u013b\u0005E\u0000\u0000\u013b\'"+ - "\u0001\u0000\u0000\u0000\u013c\u013d\u0005\r\u0000\u0000\u013d\u0142\u0003"+ - " \u0010\u0000\u013e\u013f\u0005&\u0000\u0000\u013f\u0141\u0003 \u0010"+ - "\u0000\u0140\u013e\u0001\u0000\u0000\u0000\u0141\u0144\u0001\u0000\u0000"+ - "\u0000\u0142\u0140\u0001\u0000\u0000\u0000\u0142\u0143\u0001\u0000\u0000"+ - "\u0000\u0143\u0146\u0001\u0000\u0000\u0000\u0144\u0142\u0001\u0000\u0000"+ - "\u0000\u0145\u0147\u0003\u001a\r\u0000\u0146\u0145\u0001\u0000\u0000\u0000"+ - "\u0146\u0147\u0001\u0000\u0000\u0000\u0147\u014a\u0001\u0000\u0000\u0000"+ - "\u0148\u0149\u0005!\u0000\u0000\u0149\u014b\u0003\u001a\r\u0000\u014a"+ - "\u0148\u0001\u0000\u0000\u0000\u014a\u014b\u0001\u0000\u0000\u0000\u014b"+ - ")\u0001\u0000\u0000\u0000\u014c\u014d\u0005\u0004\u0000\u0000\u014d\u014e"+ - "\u0003\u001a\r\u0000\u014e+\u0001\u0000\u0000\u0000\u014f\u0151\u0005"+ - "\u0013\u0000\u0000\u0150\u0152\u0003\u001a\r\u0000\u0151\u0150\u0001\u0000"+ - "\u0000\u0000\u0151\u0152\u0001\u0000\u0000\u0000\u0152\u0155\u0001\u0000"+ - "\u0000\u0000\u0153\u0154\u0005!\u0000\u0000\u0154\u0156\u0003\u001a\r"+ - "\u0000\u0155\u0153\u0001\u0000\u0000\u0000\u0155\u0156\u0001\u0000\u0000"+ - "\u0000\u0156-\u0001\u0000\u0000\u0000\u0157\u0158\u0005\b\u0000\u0000"+ - "\u0158\u015b\u0003\u001a\r\u0000\u0159\u015a\u0005!\u0000\u0000\u015a"+ - "\u015c\u0003\u001a\r\u0000\u015b\u0159\u0001\u0000\u0000\u0000\u015b\u015c"+ - "\u0001\u0000\u0000\u0000\u015c/\u0001\u0000\u0000\u0000\u015d\u0162\u0003"+ - "6\u001b\u0000\u015e\u015f\u0005(\u0000\u0000\u015f\u0161\u00036\u001b"+ - "\u0000\u0160\u015e\u0001\u0000\u0000\u0000\u0161\u0164\u0001\u0000\u0000"+ - "\u0000\u0162\u0160\u0001\u0000\u0000\u0000\u0162\u0163\u0001\u0000\u0000"+ - "\u0000\u01631\u0001\u0000\u0000\u0000\u0164\u0162\u0001\u0000\u0000\u0000"+ - "\u0165\u016a\u00038\u001c\u0000\u0166\u0167\u0005(\u0000\u0000\u0167\u0169"+ - "\u00038\u001c\u0000\u0168\u0166\u0001\u0000\u0000\u0000\u0169\u016c\u0001"+ - "\u0000\u0000\u0000\u016a\u0168\u0001\u0000\u0000\u0000\u016a\u016b\u0001"+ - "\u0000\u0000\u0000\u016b3\u0001\u0000\u0000\u0000\u016c\u016a\u0001\u0000"+ - "\u0000\u0000\u016d\u0172\u00032\u0019\u0000\u016e\u016f\u0005&\u0000\u0000"+ - "\u016f\u0171\u00032\u0019\u0000\u0170\u016e\u0001\u0000\u0000\u0000\u0171"+ - "\u0174\u0001\u0000\u0000\u0000\u0172\u0170\u0001\u0000\u0000\u0000\u0172"+ - "\u0173\u0001\u0000\u0000\u0000\u01735\u0001\u0000\u0000\u0000\u0174\u0172"+ - "\u0001\u0000\u0000\u0000\u0175\u0176\u0007\u0002\u0000\u0000\u01767\u0001"+ - "\u0000\u0000\u0000\u0177\u0178\u0005O\u0000\u0000\u01789\u0001\u0000\u0000"+ - "\u0000\u0179\u01a4\u00051\u0000\u0000\u017a\u017b\u0003Z-\u0000\u017b"+ - "\u017c\u0005F\u0000\u0000\u017c\u01a4\u0001\u0000\u0000\u0000\u017d\u01a4"+ - "\u0003X,\u0000\u017e\u01a4\u0003Z-\u0000\u017f\u01a4\u0003T*\u0000\u0180"+ - "\u01a4\u00054\u0000\u0000\u0181\u01a4\u0003\\.\u0000\u0182\u0183\u0005"+ - "D\u0000\u0000\u0183\u0188\u0003V+\u0000\u0184\u0185\u0005&\u0000\u0000"+ - "\u0185\u0187\u0003V+\u0000\u0186\u0184\u0001\u0000\u0000\u0000\u0187\u018a"+ - "\u0001\u0000\u0000\u0000\u0188\u0186\u0001\u0000\u0000\u0000\u0188\u0189"+ - "\u0001\u0000\u0000\u0000\u0189\u018b\u0001\u0000\u0000\u0000\u018a\u0188"+ - "\u0001\u0000\u0000\u0000\u018b\u018c\u0005E\u0000\u0000\u018c\u01a4\u0001"+ - "\u0000\u0000\u0000\u018d\u018e\u0005D\u0000\u0000\u018e\u0193\u0003T*"+ - "\u0000\u018f\u0190\u0005&\u0000\u0000\u0190\u0192\u0003T*\u0000\u0191"+ - "\u018f\u0001\u0000\u0000\u0000\u0192\u0195\u0001\u0000\u0000\u0000\u0193"+ - "\u0191\u0001\u0000\u0000\u0000\u0193\u0194\u0001\u0000\u0000\u0000\u0194"+ - "\u0196\u0001\u0000\u0000\u0000\u0195\u0193\u0001\u0000\u0000\u0000\u0196"+ - "\u0197\u0005E\u0000\u0000\u0197\u01a4\u0001\u0000\u0000\u0000\u0198\u0199"+ - "\u0005D\u0000\u0000\u0199\u019e\u0003\\.\u0000\u019a\u019b\u0005&\u0000"+ - "\u0000\u019b\u019d\u0003\\.\u0000\u019c\u019a\u0001\u0000\u0000\u0000"+ - "\u019d\u01a0\u0001\u0000\u0000\u0000\u019e\u019c\u0001\u0000\u0000\u0000"+ - "\u019e\u019f\u0001\u0000\u0000\u0000\u019f\u01a1\u0001\u0000\u0000\u0000"+ - "\u01a0\u019e\u0001\u0000\u0000\u0000\u01a1\u01a2\u0005E\u0000\u0000\u01a2"+ - "\u01a4\u0001\u0000\u0000\u0000\u01a3\u0179\u0001\u0000\u0000\u0000\u01a3"+ - "\u017a\u0001\u0000\u0000\u0000\u01a3\u017d\u0001\u0000\u0000\u0000\u01a3"+ - "\u017e\u0001\u0000\u0000\u0000\u01a3\u017f\u0001\u0000\u0000\u0000\u01a3"+ - "\u0180\u0001\u0000\u0000\u0000\u01a3\u0181\u0001\u0000\u0000\u0000\u01a3"+ - "\u0182\u0001\u0000\u0000\u0000\u01a3\u018d\u0001\u0000\u0000\u0000\u01a3"+ - "\u0198\u0001\u0000\u0000\u0000\u01a4;\u0001\u0000\u0000\u0000\u01a5\u01a6"+ - "\u0005\n\u0000\u0000\u01a6\u01a7\u0005\u001f\u0000\u0000\u01a7=\u0001"+ - "\u0000\u0000\u0000\u01a8\u01a9\u0005\u0012\u0000\u0000\u01a9\u01ae\u0003"+ - "@ \u0000\u01aa\u01ab\u0005&\u0000\u0000\u01ab\u01ad\u0003@ \u0000\u01ac"+ - "\u01aa\u0001\u0000\u0000\u0000\u01ad\u01b0\u0001\u0000\u0000\u0000\u01ae"+ - "\u01ac\u0001\u0000\u0000\u0000\u01ae\u01af\u0001\u0000\u0000\u0000\u01af"+ - "?\u0001\u0000\u0000\u0000\u01b0\u01ae\u0001\u0000\u0000\u0000\u01b1\u01b3"+ - "\u0003\n\u0005\u0000\u01b2\u01b4\u0007\u0003\u0000\u0000\u01b3\u01b2\u0001"+ - "\u0000\u0000\u0000\u01b3\u01b4\u0001\u0000\u0000\u0000\u01b4\u01b7\u0001"+ - "\u0000\u0000\u0000\u01b5\u01b6\u00052\u0000\u0000\u01b6\u01b8\u0007\u0004"+ - "\u0000\u0000\u01b7\u01b5\u0001\u0000\u0000\u0000\u01b7\u01b8\u0001\u0000"+ - "\u0000\u0000\u01b8A\u0001\u0000\u0000\u0000\u01b9\u01ba\u0005\t\u0000"+ - "\u0000\u01ba\u01bb\u00034\u001a\u0000\u01bbC\u0001\u0000\u0000\u0000\u01bc"+ - "\u01bd\u0005\u0002\u0000\u0000\u01bd\u01be\u00034\u001a\u0000\u01beE\u0001"+ - "\u0000\u0000\u0000\u01bf\u01c0\u0005\u000f\u0000\u0000\u01c0\u01c5\u0003"+ - "H$\u0000\u01c1\u01c2\u0005&\u0000\u0000\u01c2\u01c4\u0003H$\u0000\u01c3"+ - "\u01c1\u0001\u0000\u0000\u0000\u01c4\u01c7\u0001\u0000\u0000\u0000\u01c5"+ - "\u01c3\u0001\u0000\u0000\u0000\u01c5\u01c6\u0001\u0000\u0000\u0000\u01c6"+ - "G\u0001\u0000\u0000\u0000\u01c7\u01c5\u0001\u0000\u0000\u0000\u01c8\u01c9"+ - "\u00032\u0019\u0000\u01c9\u01ca\u0005S\u0000\u0000\u01ca\u01cb\u00032"+ - "\u0019\u0000\u01cbI\u0001\u0000\u0000\u0000\u01cc\u01cd\u0005\u0001\u0000"+ - "\u0000\u01cd\u01ce\u0003\u0012\t\u0000\u01ce\u01d0\u0003\\.\u0000\u01cf"+ - "\u01d1\u0003P(\u0000\u01d0\u01cf\u0001\u0000\u0000\u0000\u01d0\u01d1\u0001"+ - "\u0000\u0000\u0000\u01d1K\u0001\u0000\u0000\u0000\u01d2\u01d3\u0005\u0007"+ - "\u0000\u0000\u01d3\u01d4\u0003\u0012\t\u0000\u01d4\u01d5\u0003\\.\u0000"+ - "\u01d5M\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005\u000e\u0000\u0000\u01d7"+ - "\u01d8\u00030\u0018\u0000\u01d8O\u0001\u0000\u0000\u0000\u01d9\u01de\u0003"+ - "R)\u0000\u01da\u01db\u0005&\u0000\u0000\u01db\u01dd\u0003R)\u0000\u01dc"+ - "\u01da\u0001\u0000\u0000\u0000\u01dd\u01e0\u0001\u0000\u0000\u0000\u01de"+ - "\u01dc\u0001\u0000\u0000\u0000\u01de\u01df\u0001\u0000\u0000\u0000\u01df"+ - "Q\u0001\u0000\u0000\u0000\u01e0\u01de\u0001\u0000\u0000\u0000\u01e1\u01e2"+ - "\u00036\u001b\u0000\u01e2\u01e3\u0005$\u0000\u0000\u01e3\u01e4\u0003:"+ - "\u001d\u0000\u01e4S\u0001\u0000\u0000\u0000\u01e5\u01e6\u0007\u0005\u0000"+ - "\u0000\u01e6U\u0001\u0000\u0000\u0000\u01e7\u01ea\u0003X,\u0000\u01e8"+ - "\u01ea\u0003Z-\u0000\u01e9\u01e7\u0001\u0000\u0000\u0000\u01e9\u01e8\u0001"+ - "\u0000\u0000\u0000\u01eaW\u0001\u0000\u0000\u0000\u01eb\u01ed\u0007\u0000"+ - "\u0000\u0000\u01ec\u01eb\u0001\u0000\u0000\u0000\u01ec\u01ed\u0001\u0000"+ - "\u0000\u0000\u01ed\u01ee\u0001\u0000\u0000\u0000\u01ee\u01ef\u0005 \u0000"+ - "\u0000\u01efY\u0001\u0000\u0000\u0000\u01f0\u01f2\u0007\u0000\u0000\u0000"+ - "\u01f1\u01f0\u0001\u0000\u0000\u0000\u01f1\u01f2\u0001\u0000\u0000\u0000"+ - "\u01f2\u01f3\u0001\u0000\u0000\u0000\u01f3\u01f4\u0005\u001f\u0000\u0000"+ - "\u01f4[\u0001\u0000\u0000\u0000\u01f5\u01f6\u0005\u001e\u0000\u0000\u01f6"+ - "]\u0001\u0000\u0000\u0000\u01f7\u01f8\u0007\u0006\u0000\u0000\u01f8_\u0001"+ - "\u0000\u0000\u0000\u01f9\u01fa\u0005\u0005\u0000\u0000\u01fa\u01fb\u0003"+ - "b1\u0000\u01fba\u0001\u0000\u0000\u0000\u01fc\u01fd\u0005D\u0000\u0000"+ - "\u01fd\u01fe\u0003\u0002\u0001\u0000\u01fe\u01ff\u0005E\u0000\u0000\u01ff"+ - "c\u0001\u0000\u0000\u0000\u0200\u0201\u0005\u0011\u0000\u0000\u0201\u0202"+ - "\u0005i\u0000\u0000\u0202e\u0001\u0000\u0000\u0000\u0203\u0204\u0005\f"+ - "\u0000\u0000\u0204\u0205\u0005m\u0000\u0000\u0205g\u0001\u0000\u0000\u0000"+ - "\u0206\u0207\u0005\u0003\u0000\u0000\u0207\u020a\u0005Y\u0000\u0000\u0208"+ - "\u0209\u0005W\u0000\u0000\u0209\u020b\u00032\u0019\u0000\u020a\u0208\u0001"+ - "\u0000\u0000\u0000\u020a\u020b\u0001\u0000\u0000\u0000\u020b\u0215\u0001"+ - "\u0000\u0000\u0000\u020c\u020d\u0005X\u0000\u0000\u020d\u0212\u0003j5"+ - "\u0000\u020e\u020f\u0005&\u0000\u0000\u020f\u0211\u0003j5\u0000\u0210"+ - "\u020e\u0001\u0000\u0000\u0000\u0211\u0214\u0001\u0000\u0000\u0000\u0212"+ - "\u0210\u0001\u0000\u0000\u0000\u0212\u0213\u0001\u0000\u0000\u0000\u0213"+ - "\u0216\u0001\u0000\u0000\u0000\u0214\u0212\u0001\u0000\u0000\u0000\u0215"+ - "\u020c\u0001\u0000\u0000\u0000\u0215\u0216\u0001\u0000\u0000\u0000\u0216"+ - "i\u0001\u0000\u0000\u0000\u0217\u0218\u00032\u0019\u0000\u0218\u0219\u0005"+ - "$\u0000\u0000\u0219\u021b\u0001\u0000\u0000\u0000\u021a\u0217\u0001\u0000"+ - "\u0000\u0000\u021a\u021b\u0001\u0000\u0000\u0000\u021b\u021c\u0001\u0000"+ - "\u0000\u0000\u021c\u021d\u00032\u0019\u0000\u021dk\u0001\u0000\u0000\u0000"+ - "\u021e\u021f\u0005\u000b\u0000\u0000\u021f\u0220\u0005\u0019\u0000\u0000"+ - "\u0220\u0221\u0005W\u0000\u0000\u0221\u0222\u00034\u001a\u0000\u0222m"+ - "\u0001\u0000\u0000\u00004y\u0082\u0092\u009e\u00a7\u00af\u00b3\u00bb\u00bd"+ - "\u00c2\u00c9\u00ce\u00d5\u00db\u00e3\u00e5\u00f0\u00f7\u0102\u0105\u0113"+ - "\u011b\u0123\u0127\u012d\u0135\u0142\u0146\u014a\u0151\u0155\u015b\u0162"+ - "\u016a\u0172\u0188\u0193\u019e\u01a3\u01ae\u01b3\u01b7\u01c5\u01d0\u01de"+ - "\u01e9\u01ec\u01f1\u020a\u0212\u0215\u021a"; + "\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0005\u001d\u0189"+ + "\b\u001d\n\u001d\f\u001d\u018c\t\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ + "\u0001\u001d\u0001\u001d\u0001\u001d\u0005\u001d\u0194\b\u001d\n\u001d"+ + "\f\u001d\u0197\t\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ + "\u0001\u001d\u0001\u001d\u0005\u001d\u019f\b\u001d\n\u001d\f\u001d\u01a2"+ + "\t\u001d\u0001\u001d\u0001\u001d\u0003\u001d\u01a6\b\u001d\u0001\u001e"+ + "\u0001\u001e\u0003\u001e\u01aa\b\u001e\u0001\u001f\u0001\u001f\u0001\u001f"+ + "\u0001 \u0001 \u0001 \u0001 \u0005 \u01b3\b \n \f \u01b6\t \u0001!\u0001"+ + "!\u0003!\u01ba\b!\u0001!\u0001!\u0003!\u01be\b!\u0001\"\u0001\"\u0001"+ + "\"\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0005$\u01ca\b$\n"+ + "$\f$\u01cd\t$\u0001%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&"+ + "\u0003&\u01d7\b&\u0001\'\u0001\'\u0001\'\u0001\'\u0001(\u0001(\u0001("+ + "\u0001)\u0001)\u0001)\u0005)\u01e3\b)\n)\f)\u01e6\t)\u0001*\u0001*\u0001"+ + "*\u0001*\u0001+\u0001+\u0001,\u0001,\u0003,\u01f0\b,\u0001-\u0003-\u01f3"+ + "\b-\u0001-\u0001-\u0001.\u0003.\u01f8\b.\u0001.\u0001.\u0001/\u0001/\u0001"+ + "0\u00010\u00011\u00011\u00011\u00012\u00012\u00012\u00012\u00013\u0001"+ + "3\u00013\u00014\u00014\u00014\u00015\u00015\u00015\u00015\u00035\u0211"+ + "\b5\u00015\u00015\u00015\u00015\u00055\u0217\b5\n5\f5\u021a\t5\u00035"+ + "\u021c\b5\u00016\u00016\u00016\u00036\u0221\b6\u00016\u00016\u00017\u0001"+ + "7\u00017\u00017\u00017\u00017\u0000\u0004\u0002\n\u0010\u00128\u0000\u0002"+ + "\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e"+ + " \"$&(*,.02468:<>@BDFHJLNPRTVXZ\\^`bdfhjln\u0000\u0007\u0001\u0000?@\u0001"+ + "\u0000AC\u0001\u0000GH\u0002\u0000##\'\'\u0001\u0000*+\u0002\u0000))7"+ + "7\u0002\u000088:>\u0244\u0000p\u0001\u0000\u0000\u0000\u0002s\u0001\u0000"+ + "\u0000\u0000\u0004\u0084\u0001\u0000\u0000\u0000\u0006\u0094\u0001\u0000"+ + "\u0000\u0000\b\u0096\u0001\u0000\u0000\u0000\n\u00b5\u0001\u0000\u0000"+ + "\u0000\f\u00d0\u0001\u0000\u0000\u0000\u000e\u00d7\u0001\u0000\u0000\u0000"+ + "\u0010\u00dd\u0001\u0000\u0000\u0000\u0012\u00f2\u0001\u0000\u0000\u0000"+ + "\u0014\u00fc\u0001\u0000\u0000\u0000\u0016\u010b\u0001\u0000\u0000\u0000"+ + "\u0018\u010d\u0001\u0000\u0000\u0000\u001a\u0110\u0001\u0000\u0000\u0000"+ + "\u001c\u011d\u0001\u0000\u0000\u0000\u001e\u011f\u0001\u0000\u0000\u0000"+ + " \u012b\u0001\u0000\u0000\u0000\"\u012f\u0001\u0000\u0000\u0000$\u0131"+ + "\u0001\u0000\u0000\u0000&\u013a\u0001\u0000\u0000\u0000(\u013e\u0001\u0000"+ + "\u0000\u0000*\u014e\u0001\u0000\u0000\u0000,\u0151\u0001\u0000\u0000\u0000"+ + ".\u0159\u0001\u0000\u0000\u00000\u015f\u0001\u0000\u0000\u00002\u0167"+ + "\u0001\u0000\u0000\u00004\u016f\u0001\u0000\u0000\u00006\u0177\u0001\u0000"+ + "\u0000\u00008\u0179\u0001\u0000\u0000\u0000:\u01a5\u0001\u0000\u0000\u0000"+ + "<\u01a9\u0001\u0000\u0000\u0000>\u01ab\u0001\u0000\u0000\u0000@\u01ae"+ + "\u0001\u0000\u0000\u0000B\u01b7\u0001\u0000\u0000\u0000D\u01bf\u0001\u0000"+ + "\u0000\u0000F\u01c2\u0001\u0000\u0000\u0000H\u01c5\u0001\u0000\u0000\u0000"+ + "J\u01ce\u0001\u0000\u0000\u0000L\u01d2\u0001\u0000\u0000\u0000N\u01d8"+ + "\u0001\u0000\u0000\u0000P\u01dc\u0001\u0000\u0000\u0000R\u01df\u0001\u0000"+ + "\u0000\u0000T\u01e7\u0001\u0000\u0000\u0000V\u01eb\u0001\u0000\u0000\u0000"+ + "X\u01ef\u0001\u0000\u0000\u0000Z\u01f2\u0001\u0000\u0000\u0000\\\u01f7"+ + "\u0001\u0000\u0000\u0000^\u01fb\u0001\u0000\u0000\u0000`\u01fd\u0001\u0000"+ + "\u0000\u0000b\u01ff\u0001\u0000\u0000\u0000d\u0202\u0001\u0000\u0000\u0000"+ + "f\u0206\u0001\u0000\u0000\u0000h\u0209\u0001\u0000\u0000\u0000j\u020c"+ + "\u0001\u0000\u0000\u0000l\u0220\u0001\u0000\u0000\u0000n\u0224\u0001\u0000"+ + "\u0000\u0000pq\u0003\u0002\u0001\u0000qr\u0005\u0000\u0000\u0001r\u0001"+ + "\u0001\u0000\u0000\u0000st\u0006\u0001\uffff\uffff\u0000tu\u0003\u0004"+ + "\u0002\u0000u{\u0001\u0000\u0000\u0000vw\n\u0001\u0000\u0000wx\u0005\u001d"+ + "\u0000\u0000xz\u0003\u0006\u0003\u0000yv\u0001\u0000\u0000\u0000z}\u0001"+ + "\u0000\u0000\u0000{y\u0001\u0000\u0000\u0000{|\u0001\u0000\u0000\u0000"+ + "|\u0003\u0001\u0000\u0000\u0000}{\u0001\u0000\u0000\u0000~\u0085\u0003"+ + "b1\u0000\u007f\u0085\u0003\u001e\u000f\u0000\u0080\u0085\u0003\u0018\f"+ + "\u0000\u0081\u0085\u0003(\u0014\u0000\u0082\u0085\u0003f3\u0000\u0083"+ + "\u0085\u0003h4\u0000\u0084~\u0001\u0000\u0000\u0000\u0084\u007f\u0001"+ + "\u0000\u0000\u0000\u0084\u0080\u0001\u0000\u0000\u0000\u0084\u0081\u0001"+ + "\u0000\u0000\u0000\u0084\u0082\u0001\u0000\u0000\u0000\u0084\u0083\u0001"+ + "\u0000\u0000\u0000\u0085\u0005\u0001\u0000\u0000\u0000\u0086\u0095\u0003"+ + "*\u0015\u0000\u0087\u0095\u0003.\u0017\u0000\u0088\u0095\u0003>\u001f"+ + "\u0000\u0089\u0095\u0003n7\u0000\u008a\u0095\u0003D\"\u0000\u008b\u0095"+ + "\u0003@ \u0000\u008c\u0095\u0003,\u0016\u0000\u008d\u0095\u0003\b\u0004"+ + "\u0000\u008e\u0095\u0003F#\u0000\u008f\u0095\u0003H$\u0000\u0090\u0095"+ + "\u0003L&\u0000\u0091\u0095\u0003N\'\u0000\u0092\u0095\u0003j5\u0000\u0093"+ + "\u0095\u0003P(\u0000\u0094\u0086\u0001\u0000\u0000\u0000\u0094\u0087\u0001"+ + "\u0000\u0000\u0000\u0094\u0088\u0001\u0000\u0000\u0000\u0094\u0089\u0001"+ + "\u0000\u0000\u0000\u0094\u008a\u0001\u0000\u0000\u0000\u0094\u008b\u0001"+ + "\u0000\u0000\u0000\u0094\u008c\u0001\u0000\u0000\u0000\u0094\u008d\u0001"+ + "\u0000\u0000\u0000\u0094\u008e\u0001\u0000\u0000\u0000\u0094\u008f\u0001"+ + "\u0000\u0000\u0000\u0094\u0090\u0001\u0000\u0000\u0000\u0094\u0091\u0001"+ + "\u0000\u0000\u0000\u0094\u0092\u0001\u0000\u0000\u0000\u0094\u0093\u0001"+ + "\u0000\u0000\u0000\u0095\u0007\u0001\u0000\u0000\u0000\u0096\u0097\u0005"+ + "\u0014\u0000\u0000\u0097\u0098\u0003\n\u0005\u0000\u0098\t\u0001\u0000"+ + "\u0000\u0000\u0099\u009a\u0006\u0005\uffff\uffff\u0000\u009a\u009b\u0005"+ + "0\u0000\u0000\u009b\u00b6\u0003\n\u0005\u0007\u009c\u00b6\u0003\u000e"+ + "\u0007\u0000\u009d\u00b6\u0003\f\u0006\u0000\u009e\u00a0\u0003\u000e\u0007"+ + "\u0000\u009f\u00a1\u00050\u0000\u0000\u00a0\u009f\u0001\u0000\u0000\u0000"+ + "\u00a0\u00a1\u0001\u0000\u0000\u0000\u00a1\u00a2\u0001\u0000\u0000\u0000"+ + "\u00a2\u00a3\u0005-\u0000\u0000\u00a3\u00a4\u0005,\u0000\u0000\u00a4\u00a9"+ + "\u0003\u000e\u0007\u0000\u00a5\u00a6\u0005&\u0000\u0000\u00a6\u00a8\u0003"+ + "\u000e\u0007\u0000\u00a7\u00a5\u0001\u0000\u0000\u0000\u00a8\u00ab\u0001"+ + "\u0000\u0000\u0000\u00a9\u00a7\u0001\u0000\u0000\u0000\u00a9\u00aa\u0001"+ + "\u0000\u0000\u0000\u00aa\u00ac\u0001\u0000\u0000\u0000\u00ab\u00a9\u0001"+ + "\u0000\u0000\u0000\u00ac\u00ad\u00056\u0000\u0000\u00ad\u00b6\u0001\u0000"+ + "\u0000\u0000\u00ae\u00af\u0003\u000e\u0007\u0000\u00af\u00b1\u0005.\u0000"+ + "\u0000\u00b0\u00b2\u00050\u0000\u0000\u00b1\u00b0\u0001\u0000\u0000\u0000"+ + "\u00b1\u00b2\u0001\u0000\u0000\u0000\u00b2\u00b3\u0001\u0000\u0000\u0000"+ + "\u00b3\u00b4\u00051\u0000\u0000\u00b4\u00b6\u0001\u0000\u0000\u0000\u00b5"+ + "\u0099\u0001\u0000\u0000\u0000\u00b5\u009c\u0001\u0000\u0000\u0000\u00b5"+ + "\u009d\u0001\u0000\u0000\u0000\u00b5\u009e\u0001\u0000\u0000\u0000\u00b5"+ + "\u00ae\u0001\u0000\u0000\u0000\u00b6\u00bf\u0001\u0000\u0000\u0000\u00b7"+ + "\u00b8\n\u0004\u0000\u0000\u00b8\u00b9\u0005\"\u0000\u0000\u00b9\u00be"+ + "\u0003\n\u0005\u0005\u00ba\u00bb\n\u0003\u0000\u0000\u00bb\u00bc\u0005"+ + "3\u0000\u0000\u00bc\u00be\u0003\n\u0005\u0004\u00bd\u00b7\u0001\u0000"+ + "\u0000\u0000\u00bd\u00ba\u0001\u0000\u0000\u0000\u00be\u00c1\u0001\u0000"+ + "\u0000\u0000\u00bf\u00bd\u0001\u0000\u0000\u0000\u00bf\u00c0\u0001\u0000"+ + "\u0000\u0000\u00c0\u000b\u0001\u0000\u0000\u0000\u00c1\u00bf\u0001\u0000"+ + "\u0000\u0000\u00c2\u00c4\u0003\u000e\u0007\u0000\u00c3\u00c5\u00050\u0000"+ + "\u0000\u00c4\u00c3\u0001\u0000\u0000\u0000\u00c4\u00c5\u0001\u0000\u0000"+ + "\u0000\u00c5\u00c6\u0001\u0000\u0000\u0000\u00c6\u00c7\u0005/\u0000\u0000"+ + "\u00c7\u00c8\u0003^/\u0000\u00c8\u00d1\u0001\u0000\u0000\u0000\u00c9\u00cb"+ + "\u0003\u000e\u0007\u0000\u00ca\u00cc\u00050\u0000\u0000\u00cb\u00ca\u0001"+ + "\u0000\u0000\u0000\u00cb\u00cc\u0001\u0000\u0000\u0000\u00cc\u00cd\u0001"+ + "\u0000\u0000\u0000\u00cd\u00ce\u00055\u0000\u0000\u00ce\u00cf\u0003^/"+ + "\u0000\u00cf\u00d1\u0001\u0000\u0000\u0000\u00d0\u00c2\u0001\u0000\u0000"+ + "\u0000\u00d0\u00c9\u0001\u0000\u0000\u0000\u00d1\r\u0001\u0000\u0000\u0000"+ + "\u00d2\u00d8\u0003\u0010\b\u0000\u00d3\u00d4\u0003\u0010\b\u0000\u00d4"+ + "\u00d5\u0003`0\u0000\u00d5\u00d6\u0003\u0010\b\u0000\u00d6\u00d8\u0001"+ + "\u0000\u0000\u0000\u00d7\u00d2\u0001\u0000\u0000\u0000\u00d7\u00d3\u0001"+ + "\u0000\u0000\u0000\u00d8\u000f\u0001\u0000\u0000\u0000\u00d9\u00da\u0006"+ + "\b\uffff\uffff\u0000\u00da\u00de\u0003\u0012\t\u0000\u00db\u00dc\u0007"+ + "\u0000\u0000\u0000\u00dc\u00de\u0003\u0010\b\u0003\u00dd\u00d9\u0001\u0000"+ + "\u0000\u0000\u00dd\u00db\u0001\u0000\u0000\u0000\u00de\u00e7\u0001\u0000"+ + "\u0000\u0000\u00df\u00e0\n\u0002\u0000\u0000\u00e0\u00e1\u0007\u0001\u0000"+ + "\u0000\u00e1\u00e6\u0003\u0010\b\u0003\u00e2\u00e3\n\u0001\u0000\u0000"+ + "\u00e3\u00e4\u0007\u0000\u0000\u0000\u00e4\u00e6\u0003\u0010\b\u0002\u00e5"+ + "\u00df\u0001\u0000\u0000\u0000\u00e5\u00e2\u0001\u0000\u0000\u0000\u00e6"+ + "\u00e9\u0001\u0000\u0000\u0000\u00e7\u00e5\u0001\u0000\u0000\u0000\u00e7"+ + "\u00e8\u0001\u0000\u0000\u0000\u00e8\u0011\u0001\u0000\u0000\u0000\u00e9"+ + "\u00e7\u0001\u0000\u0000\u0000\u00ea\u00eb\u0006\t\uffff\uffff\u0000\u00eb"+ + "\u00f3\u0003:\u001d\u0000\u00ec\u00f3\u00030\u0018\u0000\u00ed\u00f3\u0003"+ + "\u0014\n\u0000\u00ee\u00ef\u0005,\u0000\u0000\u00ef\u00f0\u0003\n\u0005"+ + "\u0000\u00f0\u00f1\u00056\u0000\u0000\u00f1\u00f3\u0001\u0000\u0000\u0000"+ + "\u00f2\u00ea\u0001\u0000\u0000\u0000\u00f2\u00ec\u0001\u0000\u0000\u0000"+ + "\u00f2\u00ed\u0001\u0000\u0000\u0000\u00f2\u00ee\u0001\u0000\u0000\u0000"+ + "\u00f3\u00f9\u0001\u0000\u0000\u0000\u00f4\u00f5\n\u0001\u0000\u0000\u00f5"+ + "\u00f6\u0005%\u0000\u0000\u00f6\u00f8\u0003\u0016\u000b\u0000\u00f7\u00f4"+ + "\u0001\u0000\u0000\u0000\u00f8\u00fb\u0001\u0000\u0000\u0000\u00f9\u00f7"+ + "\u0001\u0000\u0000\u0000\u00f9\u00fa\u0001\u0000\u0000\u0000\u00fa\u0013"+ + "\u0001\u0000\u0000\u0000\u00fb\u00f9\u0001\u0000\u0000\u0000\u00fc\u00fd"+ + "\u00036\u001b\u0000\u00fd\u0107\u0005,\u0000\u0000\u00fe\u0108\u0005A"+ + "\u0000\u0000\u00ff\u0104\u0003\n\u0005\u0000\u0100\u0101\u0005&\u0000"+ + "\u0000\u0101\u0103\u0003\n\u0005\u0000\u0102\u0100\u0001\u0000\u0000\u0000"+ + "\u0103\u0106\u0001\u0000\u0000\u0000\u0104\u0102\u0001\u0000\u0000\u0000"+ + "\u0104\u0105\u0001\u0000\u0000\u0000\u0105\u0108\u0001\u0000\u0000\u0000"+ + "\u0106\u0104\u0001\u0000\u0000\u0000\u0107\u00fe\u0001\u0000\u0000\u0000"+ + "\u0107\u00ff\u0001\u0000\u0000\u0000\u0107\u0108\u0001\u0000\u0000\u0000"+ + "\u0108\u0109\u0001\u0000\u0000\u0000\u0109\u010a\u00056\u0000\u0000\u010a"+ + "\u0015\u0001\u0000\u0000\u0000\u010b\u010c\u00036\u001b\u0000\u010c\u0017"+ + "\u0001\u0000\u0000\u0000\u010d\u010e\u0005\u0010\u0000\u0000\u010e\u010f"+ + "\u0003\u001a\r\u0000\u010f\u0019\u0001\u0000\u0000\u0000\u0110\u0115\u0003"+ + "\u001c\u000e\u0000\u0111\u0112\u0005&\u0000\u0000\u0112\u0114\u0003\u001c"+ + "\u000e\u0000\u0113\u0111\u0001\u0000\u0000\u0000\u0114\u0117\u0001\u0000"+ + "\u0000\u0000\u0115\u0113\u0001\u0000\u0000\u0000\u0115\u0116\u0001\u0000"+ + "\u0000\u0000\u0116\u001b\u0001\u0000\u0000\u0000\u0117\u0115\u0001\u0000"+ + "\u0000\u0000\u0118\u011e\u0003\n\u0005\u0000\u0119\u011a\u00030\u0018"+ + "\u0000\u011a\u011b\u0005$\u0000\u0000\u011b\u011c\u0003\n\u0005\u0000"+ + "\u011c\u011e\u0001\u0000\u0000\u0000\u011d\u0118\u0001\u0000\u0000\u0000"+ + "\u011d\u0119\u0001\u0000\u0000\u0000\u011e\u001d\u0001\u0000\u0000\u0000"+ + "\u011f\u0120\u0005\u0006\u0000\u0000\u0120\u0125\u0003 \u0010\u0000\u0121"+ + "\u0122\u0005&\u0000\u0000\u0122\u0124\u0003 \u0010\u0000\u0123\u0121\u0001"+ + "\u0000\u0000\u0000\u0124\u0127\u0001\u0000\u0000\u0000\u0125\u0123\u0001"+ + "\u0000\u0000\u0000\u0125\u0126\u0001\u0000\u0000\u0000\u0126\u0129\u0001"+ + "\u0000\u0000\u0000\u0127\u0125\u0001\u0000\u0000\u0000\u0128\u012a\u0003"+ + "\"\u0011\u0000\u0129\u0128\u0001\u0000\u0000\u0000\u0129\u012a\u0001\u0000"+ + "\u0000\u0000\u012a\u001f\u0001\u0000\u0000\u0000\u012b\u012c\u0005\u0019"+ + "\u0000\u0000\u012c!\u0001\u0000\u0000\u0000\u012d\u0130\u0003$\u0012\u0000"+ + "\u012e\u0130\u0003&\u0013\u0000\u012f\u012d\u0001\u0000\u0000\u0000\u012f"+ + "\u012e\u0001\u0000\u0000\u0000\u0130#\u0001\u0000\u0000\u0000\u0131\u0132"+ + "\u0005L\u0000\u0000\u0132\u0137\u0003 \u0010\u0000\u0133\u0134\u0005&"+ + "\u0000\u0000\u0134\u0136\u0003 \u0010\u0000\u0135\u0133\u0001\u0000\u0000"+ + "\u0000\u0136\u0139\u0001\u0000\u0000\u0000\u0137\u0135\u0001\u0000\u0000"+ + "\u0000\u0137\u0138\u0001\u0000\u0000\u0000\u0138%\u0001\u0000\u0000\u0000"+ + "\u0139\u0137\u0001\u0000\u0000\u0000\u013a\u013b\u0005E\u0000\u0000\u013b"+ + "\u013c\u0003$\u0012\u0000\u013c\u013d\u0005F\u0000\u0000\u013d\'\u0001"+ + "\u0000\u0000\u0000\u013e\u013f\u0005\r\u0000\u0000\u013f\u0144\u0003 "+ + "\u0010\u0000\u0140\u0141\u0005&\u0000\u0000\u0141\u0143\u0003 \u0010\u0000"+ + "\u0142\u0140\u0001\u0000\u0000\u0000\u0143\u0146\u0001\u0000\u0000\u0000"+ + "\u0144\u0142\u0001\u0000\u0000\u0000\u0144\u0145\u0001\u0000\u0000\u0000"+ + "\u0145\u0148\u0001\u0000\u0000\u0000\u0146\u0144\u0001\u0000\u0000\u0000"+ + "\u0147\u0149\u0003\u001a\r\u0000\u0148\u0147\u0001\u0000\u0000\u0000\u0148"+ + "\u0149\u0001\u0000\u0000\u0000\u0149\u014c\u0001\u0000\u0000\u0000\u014a"+ + "\u014b\u0005!\u0000\u0000\u014b\u014d\u0003\u001a\r\u0000\u014c\u014a"+ + "\u0001\u0000\u0000\u0000\u014c\u014d\u0001\u0000\u0000\u0000\u014d)\u0001"+ + "\u0000\u0000\u0000\u014e\u014f\u0005\u0004\u0000\u0000\u014f\u0150\u0003"+ + "\u001a\r\u0000\u0150+\u0001\u0000\u0000\u0000\u0151\u0153\u0005\u0013"+ + "\u0000\u0000\u0152\u0154\u0003\u001a\r\u0000\u0153\u0152\u0001\u0000\u0000"+ + "\u0000\u0153\u0154\u0001\u0000\u0000\u0000\u0154\u0157\u0001\u0000\u0000"+ + "\u0000\u0155\u0156\u0005!\u0000\u0000\u0156\u0158\u0003\u001a\r\u0000"+ + "\u0157\u0155\u0001\u0000\u0000\u0000\u0157\u0158\u0001\u0000\u0000\u0000"+ + "\u0158-\u0001\u0000\u0000\u0000\u0159\u015a\u0005\b\u0000\u0000\u015a"+ + "\u015d\u0003\u001a\r\u0000\u015b\u015c\u0005!\u0000\u0000\u015c\u015e"+ + "\u0003\u001a\r\u0000\u015d\u015b\u0001\u0000\u0000\u0000\u015d\u015e\u0001"+ + "\u0000\u0000\u0000\u015e/\u0001\u0000\u0000\u0000\u015f\u0164\u00036\u001b"+ + "\u0000\u0160\u0161\u0005(\u0000\u0000\u0161\u0163\u00036\u001b\u0000\u0162"+ + "\u0160\u0001\u0000\u0000\u0000\u0163\u0166\u0001\u0000\u0000\u0000\u0164"+ + "\u0162\u0001\u0000\u0000\u0000\u0164\u0165\u0001\u0000\u0000\u0000\u0165"+ + "1\u0001\u0000\u0000\u0000\u0166\u0164\u0001\u0000\u0000\u0000\u0167\u016c"+ + "\u00038\u001c\u0000\u0168\u0169\u0005(\u0000\u0000\u0169\u016b\u00038"+ + "\u001c\u0000\u016a\u0168\u0001\u0000\u0000\u0000\u016b\u016e\u0001\u0000"+ + "\u0000\u0000\u016c\u016a\u0001\u0000\u0000\u0000\u016c\u016d\u0001\u0000"+ + "\u0000\u0000\u016d3\u0001\u0000\u0000\u0000\u016e\u016c\u0001\u0000\u0000"+ + "\u0000\u016f\u0174\u00032\u0019\u0000\u0170\u0171\u0005&\u0000\u0000\u0171"+ + "\u0173\u00032\u0019\u0000\u0172\u0170\u0001\u0000\u0000\u0000\u0173\u0176"+ + "\u0001\u0000\u0000\u0000\u0174\u0172\u0001\u0000\u0000\u0000\u0174\u0175"+ + "\u0001\u0000\u0000\u0000\u01755\u0001\u0000\u0000\u0000\u0176\u0174\u0001"+ + "\u0000\u0000\u0000\u0177\u0178\u0007\u0002\u0000\u0000\u01787\u0001\u0000"+ + "\u0000\u0000\u0179\u017a\u0005P\u0000\u0000\u017a9\u0001\u0000\u0000\u0000"+ + "\u017b\u01a6\u00051\u0000\u0000\u017c\u017d\u0003\\.\u0000\u017d\u017e"+ + "\u0005G\u0000\u0000\u017e\u01a6\u0001\u0000\u0000\u0000\u017f\u01a6\u0003"+ + "Z-\u0000\u0180\u01a6\u0003\\.\u0000\u0181\u01a6\u0003V+\u0000\u0182\u01a6"+ + "\u0003<\u001e\u0000\u0183\u01a6\u0003^/\u0000\u0184\u0185\u0005E\u0000"+ + "\u0000\u0185\u018a\u0003X,\u0000\u0186\u0187\u0005&\u0000\u0000\u0187"+ + "\u0189\u0003X,\u0000\u0188\u0186\u0001\u0000\u0000\u0000\u0189\u018c\u0001"+ + "\u0000\u0000\u0000\u018a\u0188\u0001\u0000\u0000\u0000\u018a\u018b\u0001"+ + "\u0000\u0000\u0000\u018b\u018d\u0001\u0000\u0000\u0000\u018c\u018a\u0001"+ + "\u0000\u0000\u0000\u018d\u018e\u0005F\u0000\u0000\u018e\u01a6\u0001\u0000"+ + "\u0000\u0000\u018f\u0190\u0005E\u0000\u0000\u0190\u0195\u0003V+\u0000"+ + "\u0191\u0192\u0005&\u0000\u0000\u0192\u0194\u0003V+\u0000\u0193\u0191"+ + "\u0001\u0000\u0000\u0000\u0194\u0197\u0001\u0000\u0000\u0000\u0195\u0193"+ + "\u0001\u0000\u0000\u0000\u0195\u0196\u0001\u0000\u0000\u0000\u0196\u0198"+ + "\u0001\u0000\u0000\u0000\u0197\u0195\u0001\u0000\u0000\u0000\u0198\u0199"+ + "\u0005F\u0000\u0000\u0199\u01a6\u0001\u0000\u0000\u0000\u019a\u019b\u0005"+ + "E\u0000\u0000\u019b\u01a0\u0003^/\u0000\u019c\u019d\u0005&\u0000\u0000"+ + "\u019d\u019f\u0003^/\u0000\u019e\u019c\u0001\u0000\u0000\u0000\u019f\u01a2"+ + "\u0001\u0000\u0000\u0000\u01a0\u019e\u0001\u0000\u0000\u0000\u01a0\u01a1"+ + "\u0001\u0000\u0000\u0000\u01a1\u01a3\u0001\u0000\u0000\u0000\u01a2\u01a0"+ + "\u0001\u0000\u0000\u0000\u01a3\u01a4\u0005F\u0000\u0000\u01a4\u01a6\u0001"+ + "\u0000\u0000\u0000\u01a5\u017b\u0001\u0000\u0000\u0000\u01a5\u017c\u0001"+ + "\u0000\u0000\u0000\u01a5\u017f\u0001\u0000\u0000\u0000\u01a5\u0180\u0001"+ + "\u0000\u0000\u0000\u01a5\u0181\u0001\u0000\u0000\u0000\u01a5\u0182\u0001"+ + "\u0000\u0000\u0000\u01a5\u0183\u0001\u0000\u0000\u0000\u01a5\u0184\u0001"+ + "\u0000\u0000\u0000\u01a5\u018f\u0001\u0000\u0000\u0000\u01a5\u019a\u0001"+ + "\u0000\u0000\u0000\u01a6;\u0001\u0000\u0000\u0000\u01a7\u01aa\u00054\u0000"+ + "\u0000\u01a8\u01aa\u0005D\u0000\u0000\u01a9\u01a7\u0001\u0000\u0000\u0000"+ + "\u01a9\u01a8\u0001\u0000\u0000\u0000\u01aa=\u0001\u0000\u0000\u0000\u01ab"+ + "\u01ac\u0005\n\u0000\u0000\u01ac\u01ad\u0005\u001f\u0000\u0000\u01ad?"+ + "\u0001\u0000\u0000\u0000\u01ae\u01af\u0005\u0012\u0000\u0000\u01af\u01b4"+ + "\u0003B!\u0000\u01b0\u01b1\u0005&\u0000\u0000\u01b1\u01b3\u0003B!\u0000"+ + "\u01b2\u01b0\u0001\u0000\u0000\u0000\u01b3\u01b6\u0001\u0000\u0000\u0000"+ + "\u01b4\u01b2\u0001\u0000\u0000\u0000\u01b4\u01b5\u0001\u0000\u0000\u0000"+ + "\u01b5A\u0001\u0000\u0000\u0000\u01b6\u01b4\u0001\u0000\u0000\u0000\u01b7"+ + "\u01b9\u0003\n\u0005\u0000\u01b8\u01ba\u0007\u0003\u0000\u0000\u01b9\u01b8"+ + "\u0001\u0000\u0000\u0000\u01b9\u01ba\u0001\u0000\u0000\u0000\u01ba\u01bd"+ + "\u0001\u0000\u0000\u0000\u01bb\u01bc\u00052\u0000\u0000\u01bc\u01be\u0007"+ + "\u0004\u0000\u0000\u01bd\u01bb\u0001\u0000\u0000\u0000\u01bd\u01be\u0001"+ + "\u0000\u0000\u0000\u01beC\u0001\u0000\u0000\u0000\u01bf\u01c0\u0005\t"+ + "\u0000\u0000\u01c0\u01c1\u00034\u001a\u0000\u01c1E\u0001\u0000\u0000\u0000"+ + "\u01c2\u01c3\u0005\u0002\u0000\u0000\u01c3\u01c4\u00034\u001a\u0000\u01c4"+ + "G\u0001\u0000\u0000\u0000\u01c5\u01c6\u0005\u000f\u0000\u0000\u01c6\u01cb"+ + "\u0003J%\u0000\u01c7\u01c8\u0005&\u0000\u0000\u01c8\u01ca\u0003J%\u0000"+ + "\u01c9\u01c7\u0001\u0000\u0000\u0000\u01ca\u01cd\u0001\u0000\u0000\u0000"+ + "\u01cb\u01c9\u0001\u0000\u0000\u0000\u01cb\u01cc\u0001\u0000\u0000\u0000"+ + "\u01ccI\u0001\u0000\u0000\u0000\u01cd\u01cb\u0001\u0000\u0000\u0000\u01ce"+ + "\u01cf\u00032\u0019\u0000\u01cf\u01d0\u0005T\u0000\u0000\u01d0\u01d1\u0003"+ + "2\u0019\u0000\u01d1K\u0001\u0000\u0000\u0000\u01d2\u01d3\u0005\u0001\u0000"+ + "\u0000\u01d3\u01d4\u0003\u0012\t\u0000\u01d4\u01d6\u0003^/\u0000\u01d5"+ + "\u01d7\u0003R)\u0000\u01d6\u01d5\u0001\u0000\u0000\u0000\u01d6\u01d7\u0001"+ + "\u0000\u0000\u0000\u01d7M\u0001\u0000\u0000\u0000\u01d8\u01d9\u0005\u0007"+ + "\u0000\u0000\u01d9\u01da\u0003\u0012\t\u0000\u01da\u01db\u0003^/\u0000"+ + "\u01dbO\u0001\u0000\u0000\u0000\u01dc\u01dd\u0005\u000e\u0000\u0000\u01dd"+ + "\u01de\u00030\u0018\u0000\u01deQ\u0001\u0000\u0000\u0000\u01df\u01e4\u0003"+ + "T*\u0000\u01e0\u01e1\u0005&\u0000\u0000\u01e1\u01e3\u0003T*\u0000\u01e2"+ + "\u01e0\u0001\u0000\u0000\u0000\u01e3\u01e6\u0001\u0000\u0000\u0000\u01e4"+ + "\u01e2\u0001\u0000\u0000\u0000\u01e4\u01e5\u0001\u0000\u0000\u0000\u01e5"+ + "S\u0001\u0000\u0000\u0000\u01e6\u01e4\u0001\u0000\u0000\u0000\u01e7\u01e8"+ + "\u00036\u001b\u0000\u01e8\u01e9\u0005$\u0000\u0000\u01e9\u01ea\u0003:"+ + "\u001d\u0000\u01eaU\u0001\u0000\u0000\u0000\u01eb\u01ec\u0007\u0005\u0000"+ + "\u0000\u01ecW\u0001\u0000\u0000\u0000\u01ed\u01f0\u0003Z-\u0000\u01ee"+ + "\u01f0\u0003\\.\u0000\u01ef\u01ed\u0001\u0000\u0000\u0000\u01ef\u01ee"+ + "\u0001\u0000\u0000\u0000\u01f0Y\u0001\u0000\u0000\u0000\u01f1\u01f3\u0007"+ + "\u0000\u0000\u0000\u01f2\u01f1\u0001\u0000\u0000\u0000\u01f2\u01f3\u0001"+ + "\u0000\u0000\u0000\u01f3\u01f4\u0001\u0000\u0000\u0000\u01f4\u01f5\u0005"+ + " \u0000\u0000\u01f5[\u0001\u0000\u0000\u0000\u01f6\u01f8\u0007\u0000\u0000"+ + "\u0000\u01f7\u01f6\u0001\u0000\u0000\u0000\u01f7\u01f8\u0001\u0000\u0000"+ + "\u0000\u01f8\u01f9\u0001\u0000\u0000\u0000\u01f9\u01fa\u0005\u001f\u0000"+ + "\u0000\u01fa]\u0001\u0000\u0000\u0000\u01fb\u01fc\u0005\u001e\u0000\u0000"+ + "\u01fc_\u0001\u0000\u0000\u0000\u01fd\u01fe\u0007\u0006\u0000\u0000\u01fe"+ + "a\u0001\u0000\u0000\u0000\u01ff\u0200\u0005\u0005\u0000\u0000\u0200\u0201"+ + "\u0003d2\u0000\u0201c\u0001\u0000\u0000\u0000\u0202\u0203\u0005E\u0000"+ + "\u0000\u0203\u0204\u0003\u0002\u0001\u0000\u0204\u0205\u0005F\u0000\u0000"+ + "\u0205e\u0001\u0000\u0000\u0000\u0206\u0207\u0005\u0011\u0000\u0000\u0207"+ + "\u0208\u0005j\u0000\u0000\u0208g\u0001\u0000\u0000\u0000\u0209\u020a\u0005"+ + "\f\u0000\u0000\u020a\u020b\u0005n\u0000\u0000\u020bi\u0001\u0000\u0000"+ + "\u0000\u020c\u020d\u0005\u0003\u0000\u0000\u020d\u0210\u0005Z\u0000\u0000"+ + "\u020e\u020f\u0005X\u0000\u0000\u020f\u0211\u00032\u0019\u0000\u0210\u020e"+ + "\u0001\u0000\u0000\u0000\u0210\u0211\u0001\u0000\u0000\u0000\u0211\u021b"+ + "\u0001\u0000\u0000\u0000\u0212\u0213\u0005Y\u0000\u0000\u0213\u0218\u0003"+ + "l6\u0000\u0214\u0215\u0005&\u0000\u0000\u0215\u0217\u0003l6\u0000\u0216"+ + "\u0214\u0001\u0000\u0000\u0000\u0217\u021a\u0001\u0000\u0000\u0000\u0218"+ + "\u0216\u0001\u0000\u0000\u0000\u0218\u0219\u0001\u0000\u0000\u0000\u0219"+ + "\u021c\u0001\u0000\u0000\u0000\u021a\u0218\u0001\u0000\u0000\u0000\u021b"+ + "\u0212\u0001\u0000\u0000\u0000\u021b\u021c\u0001\u0000\u0000\u0000\u021c"+ + "k\u0001\u0000\u0000\u0000\u021d\u021e\u00032\u0019\u0000\u021e\u021f\u0005"+ + "$\u0000\u0000\u021f\u0221\u0001\u0000\u0000\u0000\u0220\u021d\u0001\u0000"+ + "\u0000\u0000\u0220\u0221\u0001\u0000\u0000\u0000\u0221\u0222\u0001\u0000"+ + "\u0000\u0000\u0222\u0223\u00032\u0019\u0000\u0223m\u0001\u0000\u0000\u0000"+ + "\u0224\u0225\u0005\u000b\u0000\u0000\u0225\u0226\u0005\u0019\u0000\u0000"+ + "\u0226\u0227\u0005X\u0000\u0000\u0227\u0228\u00034\u001a\u0000\u0228o"+ + "\u0001\u0000\u0000\u00005{\u0084\u0094\u00a0\u00a9\u00b1\u00b5\u00bd\u00bf"+ + "\u00c4\u00cb\u00d0\u00d7\u00dd\u00e5\u00e7\u00f2\u00f9\u0104\u0107\u0115"+ + "\u011d\u0125\u0129\u012f\u0137\u0144\u0148\u014c\u0153\u0157\u015d\u0164"+ + "\u016c\u0174\u018a\u0195\u01a0\u01a5\u01a9\u01b4\u01b9\u01bd\u01cb\u01d6"+ + "\u01e4\u01ef\u01f2\u01f7\u0210\u0218\u021b\u0220"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java index 760e8f4cb9cd..0da4c187a3d4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java @@ -581,13 +581,13 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener { * *

    The default implementation does nothing.

    */ - @Override public void enterInputParam(EsqlBaseParser.InputParamContext ctx) { } + @Override public void enterInputParams(EsqlBaseParser.InputParamsContext ctx) { } /** * {@inheritDoc} * *

    The default implementation does nothing.

    */ - @Override public void exitInputParam(EsqlBaseParser.InputParamContext ctx) { } + @Override public void exitInputParams(EsqlBaseParser.InputParamsContext ctx) { } /** * {@inheritDoc} * @@ -636,6 +636,30 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener { *

    The default implementation does nothing.

    */ @Override public void exitStringArrayLiteral(EsqlBaseParser.StringArrayLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterInputParam(EsqlBaseParser.InputParamContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitInputParam(EsqlBaseParser.InputParamContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx) { } /** * {@inheritDoc} * diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java index aee998364f94..ea1c9aca9988 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java @@ -347,7 +347,7 @@ public class EsqlBaseParserBaseVisitor extends AbstractParseTreeVisitor im *

    The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.

    */ - @Override public T visitInputParam(EsqlBaseParser.InputParamContext ctx) { return visitChildren(ctx); } + @Override public T visitInputParams(EsqlBaseParser.InputParamsContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * @@ -376,6 +376,20 @@ public class EsqlBaseParserBaseVisitor extends AbstractParseTreeVisitor im * {@link #visitChildren} on {@code ctx}.

    */ @Override public T visitStringArrayLiteral(EsqlBaseParser.StringArrayLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitInputParam(EsqlBaseParser.InputParamContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java index 0c53191ab9ab..081deb03e835 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java @@ -526,17 +526,17 @@ public interface EsqlBaseParserListener extends ParseTreeListener { */ void exitBooleanLiteral(EsqlBaseParser.BooleanLiteralContext ctx); /** - * Enter a parse tree produced by the {@code inputParam} + * Enter a parse tree produced by the {@code inputParams} * labeled alternative in {@link EsqlBaseParser#constant}. * @param ctx the parse tree */ - void enterInputParam(EsqlBaseParser.InputParamContext ctx); + void enterInputParams(EsqlBaseParser.InputParamsContext ctx); /** - * Exit a parse tree produced by the {@code inputParam} + * Exit a parse tree produced by the {@code inputParams} * labeled alternative in {@link EsqlBaseParser#constant}. * @param ctx the parse tree */ - void exitInputParam(EsqlBaseParser.InputParamContext ctx); + void exitInputParams(EsqlBaseParser.InputParamsContext ctx); /** * Enter a parse tree produced by the {@code stringLiteral} * labeled alternative in {@link EsqlBaseParser#constant}. @@ -585,6 +585,30 @@ public interface EsqlBaseParserListener extends ParseTreeListener { * @param ctx the parse tree */ void exitStringArrayLiteral(EsqlBaseParser.StringArrayLiteralContext ctx); + /** + * Enter a parse tree produced by the {@code inputParam} + * labeled alternative in {@link EsqlBaseParser#params}. + * @param ctx the parse tree + */ + void enterInputParam(EsqlBaseParser.InputParamContext ctx); + /** + * Exit a parse tree produced by the {@code inputParam} + * labeled alternative in {@link EsqlBaseParser#params}. + * @param ctx the parse tree + */ + void exitInputParam(EsqlBaseParser.InputParamContext ctx); + /** + * Enter a parse tree produced by the {@code inputNamedOrPositionalParam} + * labeled alternative in {@link EsqlBaseParser#params}. + * @param ctx the parse tree + */ + void enterInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx); + /** + * Exit a parse tree produced by the {@code inputNamedOrPositionalParam} + * labeled alternative in {@link EsqlBaseParser#params}. + * @param ctx the parse tree + */ + void exitInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx); /** * Enter a parse tree produced by {@link EsqlBaseParser#limitCommand}. * @param ctx the parse tree diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java index 54f506c9d3b3..d1ffbd5fa0b3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java @@ -317,12 +317,12 @@ public interface EsqlBaseParserVisitor extends ParseTreeVisitor { */ T visitBooleanLiteral(EsqlBaseParser.BooleanLiteralContext ctx); /** - * Visit a parse tree produced by the {@code inputParam} + * Visit a parse tree produced by the {@code inputParams} * labeled alternative in {@link EsqlBaseParser#constant}. * @param ctx the parse tree * @return the visitor result */ - T visitInputParam(EsqlBaseParser.InputParamContext ctx); + T visitInputParams(EsqlBaseParser.InputParamsContext ctx); /** * Visit a parse tree produced by the {@code stringLiteral} * labeled alternative in {@link EsqlBaseParser#constant}. @@ -351,6 +351,20 @@ public interface EsqlBaseParserVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitStringArrayLiteral(EsqlBaseParser.StringArrayLiteralContext ctx); + /** + * Visit a parse tree produced by the {@code inputParam} + * labeled alternative in {@link EsqlBaseParser#params}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInputParam(EsqlBaseParser.InputParamContext ctx); + /** + * Visit a parse tree produced by the {@code inputNamedOrPositionalParam} + * labeled alternative in {@link EsqlBaseParser#params}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx); /** * Visit a parse tree produced by {@link EsqlBaseParser#limitCommand}. * @param ctx the parse tree diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java index 147d946dcef0..56822386b295 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java @@ -22,23 +22,23 @@ import org.elasticsearch.logging.Logger; import org.elasticsearch.xpack.esql.core.parser.CaseChangingCharStream; import org.elasticsearch.xpack.esql.core.plan.logical.LogicalPlan; -import java.util.HashMap; -import java.util.List; +import java.util.BitSet; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; import static org.elasticsearch.xpack.esql.core.parser.ParserUtils.source; +import static org.elasticsearch.xpack.esql.core.util.StringUtils.isInteger; public class EsqlParser { private static final Logger log = LogManager.getLogger(EsqlParser.class); public LogicalPlan createStatement(String query) { - return createStatement(query, List.of()); + return createStatement(query, QueryParams.EMPTY); } - public LogicalPlan createStatement(String query, List params) { + public LogicalPlan createStatement(String query, QueryParams params) { if (log.isDebugEnabled()) { log.debug("Parsing as statement: {}", query); } @@ -47,7 +47,7 @@ public class EsqlParser { private T invokeParser( String query, - List params, + QueryParams params, Function parseFunction, BiFunction result ) { @@ -57,8 +57,8 @@ public class EsqlParser { lexer.removeErrorListeners(); lexer.addErrorListener(ERROR_LISTENER); - Map paramTokens = new HashMap<>(); - TokenSource tokenSource = new ParametrizedTokenSource(lexer, paramTokens, params); + Map positionalParamTokens = params.positionalParamTokens(); + TokenSource tokenSource = new ParametrizedTokenSource(lexer, positionalParamTokens, params); CommonTokenStream tokenStream = new CommonTokenStream(tokenSource); EsqlBaseParser parser = new EsqlBaseParser(tokenStream); @@ -76,7 +76,7 @@ public class EsqlParser { log.trace("Parse tree: {}", tree.toStringTree()); } - return result.apply(new AstBuilder(paramTokens), tree); + return result.apply(new AstBuilder(params), tree); } catch (StackOverflowError e) { throw new ParsingException("ESQL statement is too large, causing stack overflow when generating the parsing tree: [{}]", query); } @@ -119,11 +119,14 @@ public class EsqlParser { private static class ParametrizedTokenSource implements TokenSource { private TokenSource delegate; - private Map paramTokens; + private Map paramTokens; private int param; - private List params; + private QueryParams params; + private BitSet paramTypes = new BitSet(3); + private static String message = "Inconsistent parameter declaration, " + + "use one of positional, named or anonymous params but not a combination of "; - ParametrizedTokenSource(TokenSource delegate, Map paramTokens, List params) { + ParametrizedTokenSource(TokenSource delegate, Map paramTokens, QueryParams params) { this.delegate = delegate; this.paramTokens = paramTokens; this.params = params; @@ -134,12 +137,21 @@ public class EsqlParser { public Token nextToken() { Token token = delegate.nextToken(); if (token.getType() == EsqlBaseLexer.PARAM) { - if (param >= params.size()) { - throw new ParsingException("Not enough actual parameters {}", params.size()); + checkAnonymousParam(token); + if (param >= params.positionalParams().size()) { + throw new ParsingException(source(token), "Not enough actual parameters {}", params.positionalParams().size()); } - paramTokens.put(token, params.get(param)); + paramTokens.put(token, params.positionalParams().get(param)); param++; } + + if (token.getType() == EsqlBaseLexer.NAMED_OR_POSITIONAL_PARAM) { + if (isInteger(token.getText().substring(1))) { + checkPositionalParam(token); + } else { + checkNamedParam(token); + } + } return token; } @@ -172,5 +184,26 @@ public class EsqlParser { public TokenFactory getTokenFactory() { return delegate.getTokenFactory(); } + + private void checkAnonymousParam(Token token) { + paramTypes.set(0); + if (paramTypes.cardinality() > 1) { + throw new ParsingException(source(token), message + "anonymous and " + (paramTypes.get(1) ? "named" : "positional")); + } + } + + private void checkNamedParam(Token token) { + paramTypes.set(1); + if (paramTypes.cardinality() > 1) { + throw new ParsingException(source(token), message + "named and " + (paramTypes.get(0) ? "anonymous" : "positional")); + } + } + + private void checkPositionalParam(Token token) { + paramTypes.set(2); + if (paramTypes.cardinality() > 1) { + throw new ParsingException(source(token), message + "positional and " + (paramTypes.get(0) ? "anonymous" : "named")); + } + } } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java index a32ae9167aeb..59801e59555b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java @@ -18,7 +18,6 @@ import org.apache.lucene.util.automaton.Operations; import org.elasticsearch.common.Strings; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; -import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Alias; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -68,7 +67,6 @@ import java.time.temporal.TemporalAmount; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -82,6 +80,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TIME_DURATION; import static org.elasticsearch.xpack.esql.core.util.NumericUtils.asLongUnsigned; import static org.elasticsearch.xpack.esql.core.util.NumericUtils.unsignedLongAsNumber; import static org.elasticsearch.xpack.esql.core.util.StringUtils.WILDCARD; +import static org.elasticsearch.xpack.esql.core.util.StringUtils.isInteger; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.bigIntegerToUnsignedLong; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.parseTemporalAmout; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToIntegral; @@ -95,9 +94,9 @@ public abstract class ExpressionBuilder extends IdentifierBuilder { */ public static final int MAX_EXPRESSION_DEPTH = 500; - private final Map params; + protected final QueryParams params; - ExpressionBuilder(Map params) { + ExpressionBuilder(QueryParams params) { this.params = params; } @@ -691,62 +690,64 @@ public abstract class ExpressionBuilder extends IdentifierBuilder { @Override public Object visitInputParam(EsqlBaseParser.InputParamContext ctx) { - TypedParamValue param = param(ctx.PARAM()); - DataType dataType = EsqlDataTypes.fromTypeName(param.type); - Source source = source(ctx); - if (dataType == null) { - throw new ParsingException(source, "Invalid parameter data type [{}]", param.type); - } - if (param.value == null) { - // no conversion is required for null values - return new Literal(source, null, dataType); - } - final DataType sourceType; - try { - sourceType = DataType.fromJava(param.value); - } catch (QlIllegalArgumentException ex) { - throw new ParsingException( - ex, - source, - "Unexpected actual parameter type [{}] for type [{}]", - param.value.getClass().getName(), - param.type - ); - } - if (sourceType == dataType) { - // no conversion is required if the value is already have correct type - return new Literal(source, param.value, dataType); - } - // otherwise we need to make sure that xcontent-serialized value is converted to the correct type - try { - - if (EsqlDataTypeConverter.canConvert(sourceType, dataType) == false) { - throw new ParsingException( - source, - "Cannot cast value [{}] of type [{}] to parameter type [{}]", - param.value, - sourceType, - dataType - ); - } - return new Literal(source, EsqlDataTypeConverter.converterFor(sourceType, dataType).convert(param.value), dataType); - } catch (QlIllegalArgumentException ex) { - throw new ParsingException(ex, source, "Unexpected actual parameter type [{}] for type [{}]", sourceType, param.type); - } + QueryParam param = paramByToken(ctx.PARAM()); + return visitParam(ctx, param); } - private TypedParamValue param(TerminalNode node) { + @Override + public Object visitInputNamedOrPositionalParam(EsqlBaseParser.InputNamedOrPositionalParamContext ctx) { + QueryParam param = paramByNameOrPosition(ctx.NAMED_OR_POSITIONAL_PARAM()); + if (param == null) { + return Literal.NULL; + } + return visitParam(ctx, param); + } + + private Object visitParam(EsqlBaseParser.ParamsContext ctx, QueryParam param) { + Source source = source(ctx); + DataType type = param.type(); + return new Literal(source, param.value(), type); + } + + QueryParam paramByToken(TerminalNode node) { if (node == null) { return null; } - Token token = node.getSymbol(); - - if (params.containsKey(token) == false) { + if (params.contains(token) == false) { throw new ParsingException(source(node), "Unexpected parameter"); } - return params.get(token); } + QueryParam paramByNameOrPosition(TerminalNode node) { + if (node == null) { + return null; + } + Token token = node.getSymbol(); + String nameOrPosition = token.getText().substring(1); + if (isInteger(nameOrPosition)) { + int index = Integer.parseInt(nameOrPosition); + if (params.get(index) == null) { + String message = ""; + int np = params.positionalParams().size(); + if (np > 0) { + message = ", did you mean " + (np == 1 ? "position 1?" : "any position between 1 and " + np + "?"); + } + params.addParsingError(new ParsingException(source(node), "No parameter is defined for position " + index + message)); + } + return params.get(index); + } else { + if (params.contains(nameOrPosition) == false) { + String message = ""; + List potentialMatches = StringUtils.findSimilar(nameOrPosition, params.namedParams().keySet()); + if (potentialMatches.size() > 0) { + message = ", did you mean " + + (potentialMatches.size() == 1 ? "[" + potentialMatches.get(0) + "]?" : "any of " + potentialMatches + "?"); + } + params.addParsingError(new ParsingException(source(node), "Unknown query parameter [" + nameOrPosition + "]" + message)); + } + return params.get(nameOrPosition); + } + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java index ec238c1fcf31..f829a7cb6ed0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java @@ -85,12 +85,25 @@ public class LogicalPlanBuilder extends ExpressionBuilder { */ public static final int MAX_QUERY_DEPTH = 500; - public LogicalPlanBuilder(Map params) { + public LogicalPlanBuilder(QueryParams params) { super(params); } protected LogicalPlan plan(ParseTree ctx) { - return ParserUtils.typedParsing(this, ctx, LogicalPlan.class); + LogicalPlan p = ParserUtils.typedParsing(this, ctx, LogicalPlan.class); + var errors = this.params.parsingErrors(); + if (errors.isEmpty()) { + return p; + } else { + StringBuilder message = new StringBuilder(); + for (int i = 0; i < errors.size(); i++) { + if (i > 0) { + message.append("; "); + } + message.append(errors.get(i).getMessage()); + } + throw new ParsingException(message.toString()); + } } protected List plans(List ctxs) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/QueryParam.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/QueryParam.java new file mode 100644 index 000000000000..022c18fdc586 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/QueryParam.java @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +package org.elasticsearch.xpack.esql.parser; + +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * Represent a strongly typed parameter value + */ +public record QueryParam(String name, Object value, DataType type) { + + public String nameValue() { + return "{" + (this.name == null ? "" : this.name + ":") + this.value + "}"; + } + + @Override + public String toString() { + return value + " [" + name + "][" + type + "]"; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/QueryParams.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/QueryParams.java new file mode 100644 index 000000000000..ebba6d3d0b48 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/QueryParams.java @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser; + +import org.antlr.v4.runtime.Token; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class QueryParams { + + public static final QueryParams EMPTY = new QueryParams(); + + // This matches the named or unnamed parameters specified in an EsqlQueryRequest.params. + private List params = new ArrayList<>(); + + // This matches the named parameters specified in an EsqlQueryRequest.params. + private Map nameToParam = new HashMap<>(); + + // This is populated by EsqlParser, each parameter marker has an entry. + private Map tokenToParam = new HashMap<>(); + + private List parsingErrors = new ArrayList<>(); + + public QueryParams() {} + + public QueryParams(List params) { + for (QueryParam p : params) { + this.params.add(p); + String name = p.name(); + if (name != null) { + nameToParam.put(name, p); + } + } + } + + public List positionalParams() { + return this.params; + } + + public QueryParam get(int index) { + return (index <= 0 || index > params.size()) ? null : params.get(index - 1); + } + + public Map namedParams() { + return this.nameToParam; + } + + public boolean contains(String paramName) { + return this.nameToParam.containsKey(paramName); + } + + public QueryParam get(String paramName) { + return nameToParam.get(paramName); + } + + public Map positionalParamTokens() { + return this.tokenToParam; + } + + public boolean contains(Token token) { + return this.tokenToParam.containsKey(token); + } + + public QueryParam get(Token tokenLocation) { + return this.tokenToParam.get(tokenLocation); + } + + public List parsingErrors() { + return this.parsingErrors; + } + + public void addParsingError(ParsingException e) { + this.parsingErrors.add(e); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/TypedParamValue.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/TypedParamValue.java deleted file mode 100644 index 74cc53e51b36..000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/TypedParamValue.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -package org.elasticsearch.xpack.esql.parser; - -import java.util.Objects; - -/** - * Represent a strongly typed parameter value - */ -public class TypedParamValue { - - public final Object value; - public final String type; - private boolean hasExplicitType; // the type is explicitly set in the request or inferred by the parser - private ContentLocation tokenLocation; // location of the token failing the parsing rules - - public TypedParamValue(String type, Object value) { - this(type, value, true); - } - - public TypedParamValue(String type, Object value, boolean hasExplicitType) { - this.value = value; - this.type = type; - this.hasExplicitType = hasExplicitType; - } - - public boolean hasExplicitType() { - return hasExplicitType; - } - - public void hasExplicitType(boolean hasExplicitType) { - this.hasExplicitType = hasExplicitType; - } - - public ContentLocation tokenLocation() { - return tokenLocation; - } - - public void tokenLocation(ContentLocation tokenLocation) { - this.tokenLocation = tokenLocation; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TypedParamValue that = (TypedParamValue) o; - return Objects.equals(value, that.value) - && Objects.equals(type, that.type) - && Objects.equals(hasExplicitType, that.hasExplicitType); - } - - @Override - public int hashCode() { - return Objects.hash(value, type, hasExplicitType); - } - - @Override - public String toString() { - return String.valueOf(value) + " [" + type + "][" + hasExplicitType + "][" + tokenLocation + "]"; - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java index 4fdc0bdab5ad..228ed6c5b4b3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java @@ -197,7 +197,7 @@ public class EsqlPlugin extends Plugin implements ActionPlugin { entries.addAll(Attribute.getNamedWriteables()); entries.add(UnsupportedAttribute.ENTRY); // TODO combine with above once these are in the same project entries.addAll(NamedExpression.getNamedWriteables()); - entries.add(UnsupportedAttribute.NAMED_EXPRESSION_ENTRY); + entries.add(UnsupportedAttribute.NAMED_EXPRESSION_ENTRY); // TODO combine with above once these are in the same project return entries; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java index 10116bb24e6b..1f5374b73466 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java @@ -46,7 +46,7 @@ import org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer; import org.elasticsearch.xpack.esql.optimizer.PhysicalOptimizerContext; import org.elasticsearch.xpack.esql.optimizer.PhysicalPlanOptimizer; import org.elasticsearch.xpack.esql.parser.EsqlParser; -import org.elasticsearch.xpack.esql.parser.TypedParamValue; +import org.elasticsearch.xpack.esql.parser.QueryParams; import org.elasticsearch.xpack.esql.plan.logical.Aggregate; import org.elasticsearch.xpack.esql.plan.logical.Enrich; import org.elasticsearch.xpack.esql.plan.logical.Keep; @@ -139,7 +139,7 @@ public class EsqlSession { ); } - private LogicalPlan parse(String query, List params) { + private LogicalPlan parse(String query, QueryParams params) { var parsed = new EsqlParser().createStatement(query, params); LOGGER.debug("Parsed logical plan:\n{}", parsed); return parsed; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java index b78958152b17..a8ad53b8bc66 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java @@ -29,12 +29,13 @@ import org.elasticsearch.tasks.TaskId; import org.elasticsearch.tasks.TaskInfo; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xcontent.NamedXContentRegistry; +import org.elasticsearch.xcontent.XContentParseException; import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.esql.Column; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.parser.TypedParamValue; +import org.elasticsearch.xpack.esql.parser.QueryParam; import java.io.IOException; import java.util.ArrayList; @@ -57,7 +58,7 @@ public class EsqlQueryRequestTests extends ESTestCase { Locale locale = randomLocale(random()); QueryBuilder filter = randomQueryBuilder(); - List params = randomParameters(); + List params = randomParameters(); boolean hasParams = params.isEmpty() == false; StringBuilder paramsString = paramsString(params, hasParams); String json = String.format(Locale.ROOT, """ @@ -75,20 +76,119 @@ public class EsqlQueryRequestTests extends ESTestCase { assertEquals(locale.toLanguageTag(), request.locale().toLanguageTag()); assertEquals(locale, request.locale()); assertEquals(filter, request.filter()); - - assertEquals(params.size(), request.params().size()); + assertEquals(params.size(), request.params().positionalParams().size()); for (int i = 0; i < params.size(); i++) { - assertEquals(params.get(i), request.params().get(i)); + assertEquals(params.get(i), request.params().positionalParams().get(i)); } } + public void testNamedParams() throws IOException { + String query = randomAlphaOfLengthBetween(1, 100); + boolean columnar = randomBoolean(); + Locale locale = randomLocale(random()); + QueryBuilder filter = randomQueryBuilder(); + + String paramsString = """ + ,"params":[ {"n1" : "8.15.0" }, { "n2" : 0.05 }, {"n3" : -799810013 }, + {"n4" : "127.0.0.1"}, {"n5" : "esql"}, {"n_6" : null}, {"n7_" : false}] }"""; + List params = new ArrayList<>(4); + params.add(new QueryParam("n1", "8.15.0", DataType.KEYWORD)); + params.add(new QueryParam("n2", 0.05, DataType.DOUBLE)); + params.add(new QueryParam("n3", -799810013, DataType.INTEGER)); + params.add(new QueryParam("n4", "127.0.0.1", DataType.KEYWORD)); + params.add(new QueryParam("n5", "esql", DataType.KEYWORD)); + params.add(new QueryParam("n_6", null, DataType.NULL)); + params.add(new QueryParam("n7_", false, DataType.BOOLEAN)); + String json = String.format(Locale.ROOT, """ + { + "query": "%s", + "columnar": %s, + "locale": "%s", + "filter": %s + %s""", query, columnar, locale.toLanguageTag(), filter, paramsString); + + EsqlQueryRequest request = parseEsqlQueryRequestSync(json); + + assertEquals(query, request.query()); + assertEquals(columnar, request.columnar()); + assertEquals(locale.toLanguageTag(), request.locale().toLanguageTag()); + assertEquals(locale, request.locale()); + assertEquals(filter, request.filter()); + assertEquals(params.size(), request.params().positionalParams().size()); + + for (int i = 0; i < request.params().positionalParams().size(); i++) { + assertEquals(params.get(i), request.params().positionalParams().get(i)); + } + } + + public void testInvalidParams() throws IOException { + String query = randomAlphaOfLengthBetween(1, 100); + boolean columnar = randomBoolean(); + Locale locale = randomLocale(random()); + QueryBuilder filter = randomQueryBuilder(); + + String paramsString1 = """ + "params":[ {"1" : "v1" }, {"1x" : "v1" }, {"_a" : "v1" }, {"@-#" : "v1" }, 1, 2]"""; + String json1 = String.format(Locale.ROOT, """ + { + %s + "query": "%s", + "columnar": %s, + "locale": "%s", + "filter": %s + }""", paramsString1, query, columnar, locale.toLanguageTag(), filter); + + Exception e1 = expectThrows(XContentParseException.class, () -> parseEsqlQueryRequestSync(json1)); + assertThat( + e1.getCause().getMessage(), + containsString( + "Failed to parse params: [2:16] [1] is not a valid parameter name, " + + "a valid parameter name starts with a letter and contains letters, digits and underscores only" + ) + ); + assertThat(e1.getCause().getMessage(), containsString("[2:31] [1x] is not a valid parameter name")); + assertThat(e1.getCause().getMessage(), containsString("[2:47] [_a] is not a valid parameter name")); + assertThat(e1.getCause().getMessage(), containsString("[2:63] [@-#] is not a valid parameter name")); + assertThat( + e1.getCause().getMessage(), + containsString( + "Params cannot contain both named and unnamed parameters; got [{1:v1}, {1x:v1}, {_a:v1}, {@-#:v1}] and [{1}, {2}]" + ) + ); + + String paramsString2 = """ + "params":[ 1, 2, {"1" : "v1" }, {"1x" : "v1" }]"""; + String json2 = String.format(Locale.ROOT, """ + { + %s + "query": "%s", + "columnar": %s, + "locale": "%s", + "filter": %s + }""", paramsString2, query, columnar, locale.toLanguageTag(), filter); + + Exception e2 = expectThrows(XContentParseException.class, () -> parseEsqlQueryRequestSync(json2)); + assertThat( + e2.getCause().getMessage(), + containsString( + "Failed to parse params: [2:22] [1] is not a valid parameter name, " + + "a valid parameter name starts with a letter and contains letters, digits and underscores only" + ) + ); + assertThat(e2.getCause().getMessage(), containsString("[2:37] [1x] is not a valid parameter name")); + assertThat( + e2.getCause().getMessage(), + containsString("Params cannot contain both named and unnamed parameters; got [{1:v1}, {1x:v1}] and [{1}, {2}]") + ); + } + public void testParseFieldsForAsync() throws IOException { String query = randomAlphaOfLengthBetween(1, 100); boolean columnar = randomBoolean(); Locale locale = randomLocale(random()); QueryBuilder filter = randomQueryBuilder(); - List params = randomParameters(); + List params = randomParameters(); boolean hasParams = params.isEmpty() == false; StringBuilder paramsString = paramsString(params, hasParams); boolean keepOnCompletion = randomBoolean(); @@ -126,10 +226,9 @@ public class EsqlQueryRequestTests extends ESTestCase { assertEquals(keepOnCompletion, request.keepOnCompletion()); assertEquals(waitForCompletion, request.waitForCompletionTimeout()); assertEquals(keepAlive, request.keepAlive()); - - assertEquals(params.size(), request.params().size()); + assertEquals(params.size(), request.params().positionalParams().size()); for (int i = 0; i < params.size(); i++) { - assertEquals(params.get(i), request.params().get(i)); + assertEquals(params.get(i), request.params().positionalParams().get(i)); } } @@ -192,7 +291,7 @@ public class EsqlQueryRequestTests extends ESTestCase { String json = """ { "query": "ROW x = 1", - "tables": {"a": {"c:keyword": ["a", "b", null, 1, 2.0, ["c", "d"], false]}} + "tables": {"a": {"c": {"keyword": ["a", "b", null, 1, 2.0, ["c", "d"], false]}}} } """; EsqlQueryRequest request = parseEsqlQueryRequest(json, randomBoolean()); @@ -223,7 +322,7 @@ public class EsqlQueryRequestTests extends ESTestCase { String json = """ { "query": "ROW x = 1", - "tables": {"a": {"c:integer": [1, 2, "3", null, [5, 6]]}} + "tables": {"a": {"c": {"integer": [1, 2, "3", null, [5, 6]]}}} } """; @@ -251,7 +350,7 @@ public class EsqlQueryRequestTests extends ESTestCase { String json = """ { "query": "ROW x = 1", - "tables": {"a": {"c:long": [1, 2, "3", null, [5, 6]]}} + "tables": {"a": {"c": {"long": [1, 2, "3", null, [5, 6]]}}} } """; @@ -279,7 +378,7 @@ public class EsqlQueryRequestTests extends ESTestCase { String json = """ { "query": "ROW x = 1", - "tables": {"a": {"c:double": [1.1, 2, "3.1415", null, [5.1, "-6"]]}} + "tables": {"a": {"c": {"double": [1.1, 2, "3.1415", null, [5.1, "-6"]]}}} } """; @@ -309,16 +408,16 @@ public class EsqlQueryRequestTests extends ESTestCase { "query": "ROW x = 1", "tables": { "t1": { - "a:long": [1], - "b:long": [1], - "c:keyword": [1], - "d:long": [1] + "a": {"long": [1]}, + "b": {"long": [1]}, + "c": {"keyword": [1]}, + "d": {"long": [1]} }, "t2": { - "a:long": [1], - "b:integer": [1], - "c:long": [1], - "d:long": [1] + "a": {"long": [1]}, + "b": {"integer": [1]}, + "c": {"long": [1]}, + "d": {"long": [1]} } } } @@ -378,22 +477,21 @@ public class EsqlQueryRequestTests extends ESTestCase { assertThat(json, equalTo(expected)); } - private List randomParameters() { + private List randomParameters() { if (randomBoolean()) { return Collections.emptyList(); } else { int len = randomIntBetween(1, 10); - List arr = new ArrayList<>(len); + List arr = new ArrayList<>(len); for (int i = 0; i < len; i++) { - boolean hasExplicitType = randomBoolean(); @SuppressWarnings("unchecked") - Supplier supplier = randomFrom( - () -> new TypedParamValue("boolean", randomBoolean(), hasExplicitType), - () -> new TypedParamValue("integer", randomInt(), hasExplicitType), - () -> new TypedParamValue("long", randomLong(), hasExplicitType), - () -> new TypedParamValue("double", randomDouble(), hasExplicitType), - () -> new TypedParamValue("null", null, hasExplicitType), - () -> new TypedParamValue("keyword", randomAlphaOfLength(10), hasExplicitType) + Supplier supplier = randomFrom( + () -> new QueryParam(null, randomBoolean(), DataType.BOOLEAN), + () -> new QueryParam(null, randomInt(), DataType.INTEGER), + () -> new QueryParam(null, randomLong(), DataType.LONG), + () -> new QueryParam(null, randomDouble(), DataType.DOUBLE), + () -> new QueryParam(null, null, DataType.NULL), + () -> new QueryParam(null, randomAlphaOfLength(10), DataType.KEYWORD) ); arr.add(supplier.get()); } @@ -401,33 +499,22 @@ public class EsqlQueryRequestTests extends ESTestCase { } } - private StringBuilder paramsString(List params, boolean hasParams) { + private StringBuilder paramsString(List params, boolean hasParams) { StringBuilder paramsString = new StringBuilder(); if (hasParams) { paramsString.append(",\"params\":["); boolean first = true; - for (TypedParamValue param : params) { + for (QueryParam param : params) { if (first == false) { paramsString.append(", "); } first = false; - if (param.hasExplicitType()) { - paramsString.append("{\"type\":\""); - paramsString.append(param.type); - paramsString.append("\",\"value\":"); - } - switch (param.type) { - case "keyword" -> { - paramsString.append("\""); - paramsString.append(param.value); - paramsString.append("\""); - } - case "integer", "long", "boolean", "null", "double" -> { - paramsString.append(param.value); - } - } - if (param.hasExplicitType()) { - paramsString.append("}"); + if (param.type() == DataType.KEYWORD) { + paramsString.append("\""); + paramsString.append(param.value()); + paramsString.append("\""); + } else if (param.type().isNumeric() || param.type() == DataType.BOOLEAN || param.type() == DataType.NULL) { + paramsString.append(param.value()); } } paramsString.append("]}"); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java index 07a364bf9196..e5f59f1ffa8a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java @@ -11,7 +11,8 @@ import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.parser.EsqlParser; -import org.elasticsearch.xpack.esql.parser.TypedParamValue; +import org.elasticsearch.xpack.esql.parser.QueryParam; +import org.elasticsearch.xpack.esql.parser.QueryParams; import org.elasticsearch.xpack.esql.type.EsqlDataTypes; import java.util.ArrayList; @@ -19,6 +20,8 @@ import java.util.List; import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning; import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.loadMapping; +import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; +import static org.elasticsearch.xpack.esql.core.type.DataType.NULL; import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -554,21 +557,21 @@ public class VerifierTests extends ESTestCase { } private String error(String query, Analyzer analyzer, Object... params) { - List parameters = new ArrayList<>(); + List parameters = new ArrayList<>(); for (Object param : params) { if (param == null) { - parameters.add(new TypedParamValue("null", null)); + parameters.add(new QueryParam(null, null, NULL)); } else if (param instanceof String) { - parameters.add(new TypedParamValue("keyword", param)); + parameters.add(new QueryParam(null, param, KEYWORD)); } else if (param instanceof Number) { - parameters.add(new TypedParamValue("param", param)); + parameters.add(new QueryParam(null, param, EsqlDataTypes.fromJava(param))); } else { throw new IllegalArgumentException("VerifierTests don't support params of type " + param.getClass()); } } VerificationException e = expectThrows( VerificationException.class, - () -> analyzer.analyze(parser.createStatement(query, parameters)) + () -> analyzer.analyze(parser.createStatement(query, new QueryParams(parameters))) ); String message = e.getMessage(); assertTrue(message.startsWith("Found ")); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java new file mode 100644 index 000000000000..a5ce5e004b19 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.test.AbstractWireTestCase; +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.NamedExpression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.EsField; +import org.elasticsearch.xpack.esql.expression.function.ReferenceAttributeTests; +import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute; +import org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput; +import org.elasticsearch.xpack.esql.session.EsqlConfiguration; +import org.elasticsearch.xpack.esql.session.EsqlConfigurationSerializationTests; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.hamcrest.Matchers.equalTo; + +public abstract class AbstractExpressionSerializationTests extends AbstractWireTestCase { + public static Source randomSource() { + int lineNumber = between(0, EXAMPLE_QUERY.length - 1); + int offset = between(0, EXAMPLE_QUERY[lineNumber].length() - 2); + int length = between(1, EXAMPLE_QUERY[lineNumber].length() - offset - 1); + String text = EXAMPLE_QUERY[lineNumber].substring(offset, offset + length); + return new Source(lineNumber + 1, offset, text); + } + + public static Expression randomChild() { + return ReferenceAttributeTests.randomReferenceAttribute(); + } + + @Override + protected final T copyInstance(T instance, TransportVersion version) throws IOException { + EsqlConfiguration config = EsqlConfigurationSerializationTests.randomConfiguration( + Arrays.stream(EXAMPLE_QUERY).collect(Collectors.joining("\n")), + Map.of() + ); + return copyInstance( + instance, + getNamedWriteableRegistry(), + (out, v) -> new PlanStreamOutput(out, new PlanNameRegistry(), config).writeNamedWriteable(v), + in -> { + PlanStreamInput pin = new PlanStreamInput(in, new PlanNameRegistry(), in.namedWriteableRegistry(), config); + @SuppressWarnings("unchecked") + T deser = (T) pin.readNamedWriteable(Expression.class); + assertThat(deser.source(), equalTo(instance.source())); + return deser; + }, + version + ); + } + + protected abstract List getNamedWriteables(); + + @Override + protected final NamedWriteableRegistry getNamedWriteableRegistry() { + List entries = new ArrayList<>(NamedExpression.getNamedWriteables()); + entries.addAll(Attribute.getNamedWriteables()); + entries.add(UnsupportedAttribute.ENTRY); + entries.addAll(EsField.getNamedWriteables()); + entries.addAll(getNamedWriteables()); + return new NamedWriteableRegistry(entries); + } + + private static final String[] EXAMPLE_QUERY = new String[] { + "I am the very model of a modern Major-Gineral,", + "I've information vegetable, animal, and mineral,", + "I know the kings of England, and I quote the fights historical", + "From Marathon to Waterloo, in order categorical;", + "I'm very well acquainted, too, with matters mathematical,", + "I understand equations, both the simple and quadratical,", + "About binomial theorem I'm teeming with a lot o' news,", + "With many cheerful facts about the square of the hypotenuse." }; +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractUnaryScalarSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractUnaryScalarSerializationTests.java new file mode 100644 index 000000000000..d8290966acbd --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractUnaryScalarSerializationTests.java @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression; + +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.scalar.UnaryScalarFunction; + +import java.io.IOException; +import java.util.List; + +public abstract class AbstractUnaryScalarSerializationTests extends AbstractExpressionSerializationTests { + protected abstract T create(Source source, Expression child); + + @Override + protected final T createTestInstance() { + return create(randomSource(), randomChild()); + } + + @Override + protected final T mutateInstance(T instance) throws IOException { + Expression child = randomValueOtherThan(instance.field(), AbstractExpressionSerializationTests::randomChild); + return create(instance.source(), child); + } + + @Override + protected List getNamedWriteables() { + return UnaryScalarFunction.getNamedWriteables(); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64SerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64SerializationTests.java new file mode 100644 index 000000000000..eee637610ffd --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64SerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class FromBase64SerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected FromBase64 create(Source source, Expression child) { + return new FromBase64(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64SerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64SerializationTests.java new file mode 100644 index 000000000000..0eebe0d74c5b --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64SerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToBase64SerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToBase64 create(Source source, Expression child) { + return new ToBase64(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanSerializationTests.java new file mode 100644 index 000000000000..0f94eb46110e --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBooleanSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToBooleanSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToBoolean create(Source source, Expression child) { + return new ToBoolean(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPointSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPointSerializationTests.java new file mode 100644 index 000000000000..601320f9fbda --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianPointSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToCartesianPointSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToCartesianPoint create(Source source, Expression child) { + return new ToCartesianPoint(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShapeSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShapeSerializationTests.java new file mode 100644 index 000000000000..96762ca28040 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToCartesianShapeSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToCartesianShapeSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToCartesianShape create(Source source, Expression child) { + return new ToCartesianShape(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetimeSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetimeSerializationTests.java new file mode 100644 index 000000000000..935269ee76f4 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatetimeSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToDatetimeSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToDatetime create(Source source, Expression child) { + return new ToDatetime(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegreesSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegreesSerializationTests.java new file mode 100644 index 000000000000..fd0f1dba4bf6 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDegreesSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToDegreesSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToDegrees create(Source source, Expression child) { + return new ToDegrees(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleSerializationTests.java new file mode 100644 index 000000000000..c2eef3b26dbb --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToDoubleSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToDouble create(Source source, Expression child) { + return new ToDouble(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPointSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPointSerializationTests.java new file mode 100644 index 000000000000..9e210a887a17 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoPointSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToGeoPointSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToGeoPoint create(Source source, Expression child) { + return new ToGeoPoint(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeSerializationTests.java new file mode 100644 index 000000000000..71e4bc335a90 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToGeoShapeSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToGeoShape create(Source source, Expression child) { + return new ToGeoShape(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPSerializationTests.java new file mode 100644 index 000000000000..76657639a583 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToIPSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToIP create(Source source, Expression child) { + return new ToIP(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerSerializationTests.java new file mode 100644 index 000000000000..3c8c47414b28 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIntegerSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToIntegerSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToInteger create(Source source, Expression child) { + return new ToInteger(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongSerializationTests.java new file mode 100644 index 000000000000..7acba8c04171 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToLongSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToLong create(Source source, Expression child) { + return new ToLong(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadiansSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadiansSerializationTests.java new file mode 100644 index 000000000000..396feb6d13a9 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToRadiansSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToRadiansSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToRadians create(Source source, Expression child) { + return new ToRadians(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringSerializationTests.java new file mode 100644 index 000000000000..08bfa106cbd9 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToStringSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToString create(Source source, Expression child) { + return new ToString(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongSerializationTests.java new file mode 100644 index 000000000000..3e58e8d4f4ad --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToUnsignedLongSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToUnsignedLongSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToUnsignedLong create(Source source, Expression child) { + return new ToUnsignedLong(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionSerializationTests.java new file mode 100644 index 000000000000..62548212d843 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToVersionSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToVersionSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToVersion create(Source source, Expression child) { + return new ToVersion(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsSerializationTests.java new file mode 100644 index 000000000000..fd447c34d3fa --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AbsSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class AbsSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Abs create(Source source, Expression child) { + return new Abs(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AcosSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AcosSerializationTests.java new file mode 100644 index 000000000000..d980fa95c3b9 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AcosSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class AcosSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Acos create(Source source, Expression child) { + return new Acos(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AsinSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AsinSerializationTests.java new file mode 100644 index 000000000000..09000388c553 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AsinSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class AsinSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Asin create(Source source, Expression child) { + return new Asin(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AtanSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AtanSerializationTests.java new file mode 100644 index 000000000000..2176f06c82a1 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/AtanSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class AtanSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Atan create(Source source, Expression child) { + return new Atan(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CbrtSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CbrtSerializationTests.java new file mode 100644 index 000000000000..294dd1d378d2 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CbrtSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class CbrtSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Cbrt create(Source source, Expression child) { + return new Cbrt(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilSerializationTests.java new file mode 100644 index 000000000000..7105a44ed9a0 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CeilSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class CeilSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Ceil create(Source source, Expression child) { + return new Ceil(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CosSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CosSerializationTests.java new file mode 100644 index 000000000000..0be0c411ebea --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CosSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class CosSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Cos create(Source source, Expression child) { + return new Cos(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshSerializationTests.java new file mode 100644 index 000000000000..cb8ee99869c2 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/CoshSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class CoshSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Cosh create(Source source, Expression child) { + return new Cosh(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorSerializationTests.java new file mode 100644 index 000000000000..48fdd68e8690 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/FloorSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class FloorSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Floor create(Source source, Expression child) { + return new Floor(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10SerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10SerializationTests.java new file mode 100644 index 000000000000..2b79bbeb8a9c --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/Log10SerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class Log10SerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Log10 create(Source source, Expression child) { + return new Log10(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinSerializationTests.java new file mode 100644 index 000000000000..c9118fceaf5f --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class SinSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Sin create(Source source, Expression child) { + return new Sin(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhSerializationTests.java new file mode 100644 index 000000000000..c87e41ef3fbb --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SinhSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class SinhSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Sinh create(Source source, Expression child) { + return new Sinh(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SqrtSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SqrtSerializationTests.java new file mode 100644 index 000000000000..526f50eaa4d2 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/SqrtSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class SqrtSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Sqrt create(Source source, Expression child) { + return new Sqrt(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/TanSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/TanSerializationTests.java new file mode 100644 index 000000000000..9c1a0a9f514c --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/TanSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class TanSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Tan create(Source source, Expression child) { + return new Tan(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/TanhSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/TanhSerializationTests.java new file mode 100644 index 000000000000..3899ad34851e --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/math/TanhSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.math; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class TanhSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Tanh create(Source source, Expression child) { + return new Tanh(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegSerializationTests.java new file mode 100644 index 000000000000..241958f12d69 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class NegSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected Neg create(Source source, Expression child) { + return new Neg(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java index b45fcd272439..2278be659c53 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java @@ -194,7 +194,7 @@ public class PlanNamedTypesTests extends ESTestCase { public void testFunctionEntries() { var serializableFunctions = PlanNamedTypes.namedTypeEntries() .stream() - .filter(e -> Function.class.isAssignableFrom(e.concreteClass())) + .filter(e -> Function.class.isAssignableFrom(e.categoryClass())) .map(PlanNameRegistry.Entry::name) .sorted() .toList(); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java index 884b24fc0fc5..28662c2470f1 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.esql.parser; -import org.apache.lucene.util.BytesRef; import org.elasticsearch.Build; import org.elasticsearch.core.Tuple; import org.elasticsearch.index.IndexMode; @@ -31,7 +30,6 @@ import org.elasticsearch.xpack.esql.core.plan.logical.Limit; import org.elasticsearch.xpack.esql.core.plan.logical.LogicalPlan; import org.elasticsearch.xpack.esql.core.plan.logical.OrderBy; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.core.util.StringUtils; import org.elasticsearch.xpack.esql.expression.function.scalar.string.RLike; import org.elasticsearch.xpack.esql.expression.function.scalar.string.WildcardLike; import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Add; @@ -52,11 +50,8 @@ import org.elasticsearch.xpack.esql.plan.logical.Lookup; import org.elasticsearch.xpack.esql.plan.logical.MvExpand; import org.elasticsearch.xpack.esql.plan.logical.Project; import org.elasticsearch.xpack.esql.plan.logical.Row; -import org.elasticsearch.xpack.versionfield.Version; import java.math.BigInteger; -import java.time.Duration; -import java.time.Period; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -68,6 +63,7 @@ import static org.elasticsearch.xpack.esql.core.expression.Literal.FALSE; import static org.elasticsearch.xpack.esql.core.expression.Literal.TRUE; import static org.elasticsearch.xpack.esql.core.expression.function.FunctionResolutionStrategy.DEFAULT; import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY; +import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.util.NumericUtils.asLongUnsigned; import static org.elasticsearch.xpack.esql.parser.ExpressionBuilder.breakIntoFragments; @@ -79,6 +75,7 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +//@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug") public class StatementParserTests extends ESTestCase { private static String FROM = "from test"; @@ -409,7 +406,7 @@ public class StatementParserTests extends ESTestCase { } public void testLimitConstraints() { - expectError("from text | limit -1", "extraneous input '-' expecting INTEGER_LITERAL"); + expectError("from text | limit -1", "line 1:19: extraneous input '-' expecting INTEGER_LITERAL"); } public void testBasicSortCommand() { @@ -770,19 +767,23 @@ public class StatementParserTests extends ESTestCase { public void testInputParams() { LogicalPlan stm = statement( - "row x = ?, y = ?, a = ?, b = ?, c = ?, d = ?", - List.of( - new TypedParamValue("integer", 1), - new TypedParamValue("keyword", "2"), - new TypedParamValue("date_period", "2 days"), - new TypedParamValue("time_duration", "4 hours"), - new TypedParamValue("version", "1.2.3"), - new TypedParamValue("ip", "127.0.0.1") + "row x = ?, y = ?, a = ?, b = ?, c = ?, d = ?, e = ?-1, f = ?+1", + new QueryParams( + List.of( + new QueryParam(null, 1, INTEGER), + new QueryParam(null, "2", KEYWORD), + new QueryParam(null, "2 days", KEYWORD), + new QueryParam(null, "4 hours", KEYWORD), + new QueryParam(null, "1.2.3", KEYWORD), + new QueryParam(null, "127.0.0.1", KEYWORD), + new QueryParam(null, 10, INTEGER), + new QueryParam(null, 10, INTEGER) + ) ) ); assertThat(stm, instanceOf(Row.class)); Row row = (Row) stm; - assertThat(row.fields().size(), is(6)); + assertThat(row.fields().size(), is(8)); NamedExpression field = row.fields().get(0); assertThat(field.name(), is("x")); @@ -800,65 +801,346 @@ public class StatementParserTests extends ESTestCase { assertThat(field.name(), is("a")); assertThat(field, instanceOf(Alias.class)); alias = (Alias) field; - assertThat(alias.child().fold(), is(Period.ofDays(2))); + assertThat(alias.child().fold(), is("2 days")); field = row.fields().get(3); assertThat(field.name(), is("b")); assertThat(field, instanceOf(Alias.class)); alias = (Alias) field; - assertThat(alias.child().fold(), is(Duration.ofHours(4))); + assertThat(alias.child().fold(), is("4 hours")); field = row.fields().get(4); assertThat(field.name(), is("c")); assertThat(field, instanceOf(Alias.class)); alias = (Alias) field; - assertThat(alias.child().fold().getClass(), is(BytesRef.class)); - assertThat(alias.child().fold().toString(), is(new Version("1.2.3").toBytesRef().toString())); + assertThat(alias.child().fold().getClass(), is(String.class)); + assertThat(alias.child().fold().toString(), is("1.2.3")); field = row.fields().get(5); assertThat(field.name(), is("d")); assertThat(field, instanceOf(Alias.class)); alias = (Alias) field; - assertThat(alias.child().fold().getClass(), is(BytesRef.class)); - assertThat(alias.child().fold().toString(), is(StringUtils.parseIP("127.0.0.1").toString())); - } + assertThat(alias.child().fold().getClass(), is(String.class)); + assertThat(alias.child().fold().toString(), is("127.0.0.1")); - public void testWrongIntervalParams() { - expectError("row x = ?", List.of(new TypedParamValue("date_period", "12")), "Cannot parse [12] to DATE_PERIOD"); - expectError("row x = ?", List.of(new TypedParamValue("time_duration", "12")), "Cannot parse [12] to TIME_DURATION"); - expectError( - "row x = ?", - List.of(new TypedParamValue("date_period", "12 months foo")), - "Cannot parse [12 months foo] to DATE_PERIOD" - ); - expectError( - "row x = ?", - List.of(new TypedParamValue("time_duration", "12 minutes bar")), - "Cannot parse [12 minutes bar] to TIME_DURATION" - ); - expectError("row x = ?", List.of(new TypedParamValue("date_period", "12 foo")), "Unexpected time interval qualifier: 'foo'"); - expectError("row x = ?", List.of(new TypedParamValue("time_duration", "12 bar")), "Unexpected time interval qualifier: 'bar'"); - expectError("row x = ?", List.of(new TypedParamValue("date_period", "foo days")), "Cannot parse [foo days] to DATE_PERIOD"); - expectError( - "row x = ?", - List.of(new TypedParamValue("time_duration", "bar seconds")), - "Cannot parse [bar seconds] to TIME_DURATION" - ); + field = row.fields().get(6); + assertThat(field.name(), is("e")); + assertThat(field, instanceOf(Alias.class)); + alias = (Alias) field; + assertThat(alias.child().fold(), is(9)); - expectError( - "row x = ?", - List.of(new TypedParamValue("date_period", "2 minutes")), - "Cannot parse [2 minutes] to DATE_PERIOD, did you mean TIME_DURATION?" - ); - expectError( - "row x = ?", - List.of(new TypedParamValue("time_duration", "11 months")), - "Cannot parse [11 months] to TIME_DURATION, did you mean DATE_PERIOD?" - ); + field = row.fields().get(7); + assertThat(field.name(), is("f")); + assertThat(field, instanceOf(Alias.class)); + alias = (Alias) field; + assertThat(alias.child().fold(), is(11)); } public void testMissingInputParams() { - expectError("row x = ?, y = ?", List.of(new TypedParamValue("integer", 1)), "Not enough actual parameters 1"); + expectError("row x = ?, y = ?", List.of(new QueryParam(null, 1, INTEGER)), "Not enough actual parameters 1"); + } + + public void testNamedParams() { + LogicalPlan stm = statement("row x=?name1, y = ?name1", new QueryParams(List.of(new QueryParam("name1", 1, INTEGER)))); + assertThat(stm, instanceOf(Row.class)); + Row row = (Row) stm; + assertThat(row.fields().size(), is(2)); + + NamedExpression field = row.fields().get(0); + assertThat(field.name(), is("x")); + assertThat(field, instanceOf(Alias.class)); + Alias alias = (Alias) field; + assertThat(alias.child().fold(), is(1)); + + field = row.fields().get(1); + assertThat(field.name(), is("y")); + assertThat(field, instanceOf(Alias.class)); + alias = (Alias) field; + assertThat(alias.child().fold(), is(1)); + } + + public void testInvalidNamedParams() { + expectError( + "from test | where x < ?n1 | eval y = ?n2", + List.of(new QueryParam("n1", 5, INTEGER)), + "Unknown query parameter [n2], did you mean [n1]?" + ); + + expectError( + "from test | where x < ?n1 | eval y = ?n2", + List.of(new QueryParam("n1", 5, INTEGER), new QueryParam("n3", 5, INTEGER)), + "Unknown query parameter [n2], did you mean any of [n1, n3]?" + ); + + expectError("from test | where x < ?_1", List.of(new QueryParam("_1", 5, INTEGER)), "extraneous input '_1' expecting "); + + expectError("from test | where x < ?#1", List.of(new QueryParam("#1", 5, INTEGER)), "token recognition error at: '#'"); + + expectError( + "from test | where x < ??", + List.of(new QueryParam("n_1", 5, INTEGER), new QueryParam("n_2", 5, INTEGER)), + "extraneous input '?' expecting " + ); + } + + public void testPositionalParams() { + LogicalPlan stm = statement("row x=?1, y=?1", new QueryParams(List.of(new QueryParam(null, 1, INTEGER)))); + assertThat(stm, instanceOf(Row.class)); + Row row = (Row) stm; + assertThat(row.fields().size(), is(2)); + + NamedExpression field = row.fields().get(0); + assertThat(field.name(), is("x")); + assertThat(field, instanceOf(Alias.class)); + Alias alias = (Alias) field; + assertThat(alias.child().fold(), is(1)); + + field = row.fields().get(1); + assertThat(field.name(), is("y")); + assertThat(field, instanceOf(Alias.class)); + alias = (Alias) field; + assertThat(alias.child().fold(), is(1)); + } + + public void testInvalidPositionalParams() { + expectError( + "from test | where x < ?0", + List.of(new QueryParam(null, 5, INTEGER)), + "No parameter is defined for position 0, did you mean position 1" + ); + + expectError( + "from test | where x < ?2", + List.of(new QueryParam(null, 5, INTEGER)), + "No parameter is defined for position 2, did you mean position 1" + ); + + expectError( + "from test | where x < ?0 and y < ?2", + List.of(new QueryParam(null, 5, INTEGER)), + "line 1:24: No parameter is defined for position 0, did you mean position 1?; " + + "line 1:35: No parameter is defined for position 2, did you mean position 1?" + ); + + expectError( + "from test | where x < ?0 and y < ?2", + List.of(new QueryParam(null, 5, INTEGER)), + "No parameter is defined for position 2, did you mean position 1" + ); + + expectError( + "from test | where x < ?0", + List.of(new QueryParam(null, 5, INTEGER), new QueryParam(null, 10, INTEGER)), + "No parameter is defined for position 0, did you mean any position between 1 and 2?" + ); + } + + public void testParamInWhere() { + LogicalPlan plan = statement("from test | where x < ? | limit 10", new QueryParams(List.of(new QueryParam(null, 5, INTEGER)))); + assertThat(plan, instanceOf(Limit.class)); + Limit limit = (Limit) plan; + assertThat(limit.limit(), instanceOf(Literal.class)); + assertThat(((Literal) limit.limit()).value(), equalTo(10)); + assertThat(limit.children().size(), equalTo(1)); + assertThat(limit.children().get(0), instanceOf(Filter.class)); + Filter w = (Filter) limit.children().get(0); + assertThat(((Literal) w.condition().children().get(1)).value(), equalTo(5)); + assertThat(limit.children().get(0).children().size(), equalTo(1)); + assertThat(limit.children().get(0).children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + + plan = statement("from test | where x < ?n1 | limit 10", new QueryParams(List.of(new QueryParam("n1", 5, INTEGER)))); + assertThat(plan, instanceOf(Limit.class)); + limit = (Limit) plan; + assertThat(limit.limit(), instanceOf(Literal.class)); + assertThat(((Literal) limit.limit()).value(), equalTo(10)); + assertThat(limit.children().size(), equalTo(1)); + assertThat(limit.children().get(0), instanceOf(Filter.class)); + w = (Filter) limit.children().get(0); + assertThat(((Literal) w.condition().children().get(1)).value(), equalTo(5)); + assertThat(limit.children().get(0).children().size(), equalTo(1)); + assertThat(limit.children().get(0).children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + + plan = statement("from test | where x < ?1 | limit 10", new QueryParams(List.of(new QueryParam(null, 5, INTEGER)))); + assertThat(plan, instanceOf(Limit.class)); + limit = (Limit) plan; + assertThat(limit.limit(), instanceOf(Literal.class)); + assertThat(((Literal) limit.limit()).value(), equalTo(10)); + assertThat(limit.children().size(), equalTo(1)); + assertThat(limit.children().get(0), instanceOf(Filter.class)); + w = (Filter) limit.children().get(0); + assertThat(((Literal) w.condition().children().get(1)).value(), equalTo(5)); + assertThat(limit.children().get(0).children().size(), equalTo(1)); + assertThat(limit.children().get(0).children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + } + + public void testParamInEval() { + LogicalPlan plan = statement( + "from test | where x < ? | eval y = ? + ? | limit 10", + new QueryParams( + List.of(new QueryParam(null, 5, INTEGER), new QueryParam(null, -1, INTEGER), new QueryParam(null, 100, INTEGER)) + ) + ); + assertThat(plan, instanceOf(Limit.class)); + Limit limit = (Limit) plan; + assertThat(limit.limit(), instanceOf(Literal.class)); + assertThat(((Literal) limit.limit()).value(), equalTo(10)); + assertThat(limit.children().size(), equalTo(1)); + assertThat(limit.children().get(0), instanceOf(Eval.class)); + Eval eval = (Eval) limit.children().get(0); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).left()).value(), equalTo(-1)); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).right()).value(), equalTo(100)); + Filter f = (Filter) eval.children().get(0); + assertThat(((Literal) f.condition().children().get(1)).value(), equalTo(5)); + assertThat(f.children().size(), equalTo(1)); + assertThat(f.children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + + plan = statement( + "from test | where x < ?n1 | eval y = ?n2 + ?n3 | limit 10", + new QueryParams( + List.of(new QueryParam("n1", 5, INTEGER), new QueryParam("n2", -1, INTEGER), new QueryParam("n3", 100, INTEGER)) + ) + ); + assertThat(plan, instanceOf(Limit.class)); + limit = (Limit) plan; + assertThat(limit.limit(), instanceOf(Literal.class)); + assertThat(((Literal) limit.limit()).value(), equalTo(10)); + assertThat(limit.children().size(), equalTo(1)); + assertThat(limit.children().get(0), instanceOf(Eval.class)); + eval = (Eval) limit.children().get(0); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).left()).value(), equalTo(-1)); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).right()).value(), equalTo(100)); + f = (Filter) eval.children().get(0); + assertThat(((Literal) f.condition().children().get(1)).value(), equalTo(5)); + assertThat(f.children().size(), equalTo(1)); + assertThat(f.children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + + plan = statement( + "from test | where x < ?1 | eval y = ?2 + ?1 | limit 10", + new QueryParams(List.of(new QueryParam(null, 5, INTEGER), new QueryParam(null, -1, INTEGER))) + ); + assertThat(plan, instanceOf(Limit.class)); + limit = (Limit) plan; + assertThat(limit.limit(), instanceOf(Literal.class)); + assertThat(((Literal) limit.limit()).value(), equalTo(10)); + assertThat(limit.children().size(), equalTo(1)); + assertThat(limit.children().get(0), instanceOf(Eval.class)); + eval = (Eval) limit.children().get(0); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).left()).value(), equalTo(-1)); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).right()).value(), equalTo(5)); + f = (Filter) eval.children().get(0); + assertThat(((Literal) f.condition().children().get(1)).value(), equalTo(5)); + assertThat(f.children().size(), equalTo(1)); + assertThat(f.children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + } + + public void testParamInAggFunction() { + LogicalPlan plan = statement( + "from test | where x < ? | eval y = ? + ? | stats count(?) by z", + new QueryParams( + List.of( + new QueryParam(null, 5, INTEGER), + new QueryParam(null, -1, INTEGER), + new QueryParam(null, 100, INTEGER), + new QueryParam(null, "*", KEYWORD) + ) + ) + ); + assertThat(plan, instanceOf(EsqlAggregate.class)); + EsqlAggregate agg = (EsqlAggregate) plan; + assertThat(((Literal) agg.aggregates().get(0).children().get(0).children().get(0)).value(), equalTo("*")); + assertThat(agg.child(), instanceOf(Eval.class)); + assertThat(agg.children().size(), equalTo(1)); + assertThat(agg.children().get(0), instanceOf(Eval.class)); + Eval eval = (Eval) agg.children().get(0); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).left()).value(), equalTo(-1)); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).right()).value(), equalTo(100)); + Filter f = (Filter) eval.children().get(0); + assertThat(((Literal) f.condition().children().get(1)).value(), equalTo(5)); + assertThat(f.children().size(), equalTo(1)); + assertThat(f.children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + + plan = statement( + "from test | where x < ?n1 | eval y = ?n2 + ?n3 | stats count(?n4) by z", + new QueryParams( + List.of( + new QueryParam("n1", 5, INTEGER), + new QueryParam("n2", -1, INTEGER), + new QueryParam("n3", 100, INTEGER), + new QueryParam("n4", "*", KEYWORD) + ) + ) + ); + assertThat(plan, instanceOf(EsqlAggregate.class)); + agg = (EsqlAggregate) plan; + assertThat(((Literal) agg.aggregates().get(0).children().get(0).children().get(0)).value(), equalTo("*")); + assertThat(agg.child(), instanceOf(Eval.class)); + assertThat(agg.children().size(), equalTo(1)); + assertThat(agg.children().get(0), instanceOf(Eval.class)); + eval = (Eval) agg.children().get(0); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).left()).value(), equalTo(-1)); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).right()).value(), equalTo(100)); + f = (Filter) eval.children().get(0); + assertThat(((Literal) f.condition().children().get(1)).value(), equalTo(5)); + assertThat(f.children().size(), equalTo(1)); + assertThat(f.children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + + plan = statement( + "from test | where x < ?1 | eval y = ?2 + ?1 | stats count(?3) by z", + new QueryParams( + List.of(new QueryParam(null, 5, INTEGER), new QueryParam(null, -1, INTEGER), new QueryParam(null, "*", KEYWORD)) + ) + ); + assertThat(plan, instanceOf(EsqlAggregate.class)); + agg = (EsqlAggregate) plan; + assertThat(((Literal) agg.aggregates().get(0).children().get(0).children().get(0)).value(), equalTo("*")); + assertThat(agg.child(), instanceOf(Eval.class)); + assertThat(agg.children().size(), equalTo(1)); + assertThat(agg.children().get(0), instanceOf(Eval.class)); + eval = (Eval) agg.children().get(0); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).left()).value(), equalTo(-1)); + assertThat(((Literal) ((Add) eval.fields().get(0).child()).right()).value(), equalTo(5)); + f = (Filter) eval.children().get(0); + assertThat(((Literal) f.condition().children().get(1)).value(), equalTo(5)); + assertThat(f.children().size(), equalTo(1)); + assertThat(f.children().get(0), instanceOf(EsqlUnresolvedRelation.class)); + } + + public void testParamMixed() { + expectError( + "from test | where x < ? | eval y = ?n2 + ?n3 | limit ?n4", + List.of( + new QueryParam("n1", 5, INTEGER), + new QueryParam("n2", -1, INTEGER), + new QueryParam("n3", 100, INTEGER), + new QueryParam("n4", 10, INTEGER) + ), + "Inconsistent parameter declaration, " + + "use one of positional, named or anonymous params but not a combination of named and anonymous" + ); + + expectError( + "from test | where x < ?1 | eval y = ?n2 + ?n3 | limit ?n4", + List.of( + new QueryParam("n1", 5, INTEGER), + new QueryParam("n2", -1, INTEGER), + new QueryParam("n3", 100, INTEGER), + new QueryParam("n4", 10, INTEGER) + ), + "Inconsistent parameter declaration, " + + "use one of positional, named or anonymous params but not a combination of named and positional" + ); + + expectError( + "from test | where x < ? | eval y = ?2 + ?n3 | limit ?n4", + List.of( + new QueryParam("n1", 5, INTEGER), + new QueryParam("n2", -1, INTEGER), + new QueryParam("n3", 100, INTEGER), + new QueryParam("n4", 10, INTEGER) + ), + "Inconsistent parameter declaration, " + + "use one of positional, named or anonymous params but not a combination of positional and anonymous" + ); } public void testFieldContainingDotsAndNumbers() { @@ -1117,10 +1399,10 @@ public class StatementParserTests extends ESTestCase { } private LogicalPlan statement(String e) { - return statement(e, List.of()); + return statement(e, QueryParams.EMPTY); } - private LogicalPlan statement(String e, List params) { + private LogicalPlan statement(String e, QueryParams params) { return parser.createStatement(e, params); } @@ -1200,8 +1482,12 @@ public class StatementParserTests extends ESTestCase { assertThat(e.getMessage(), containsString(errorMessage)); } - private void expectError(String query, List params, String errorMessage) { - ParsingException e = expectThrows(ParsingException.class, "Expected syntax error for " + query, () -> statement(query, params)); + private void expectError(String query, List params, String errorMessage) { + ParsingException e = expectThrows( + ParsingException.class, + "Expected syntax error for " + query, + () -> statement(query, new QueryParams(params)) + ); assertThat(e.getMessage(), containsString(errorMessage)); } } diff --git a/x-pack/plugin/frozen-indices/src/internalClusterTest/java/org/elasticsearch/index/engine/frozen/FrozenIndexIT.java b/x-pack/plugin/frozen-indices/src/internalClusterTest/java/org/elasticsearch/index/engine/frozen/FrozenIndexIT.java index 7b33fe670efd..e378ce06611c 100644 --- a/x-pack/plugin/frozen-indices/src/internalClusterTest/java/org/elasticsearch/index/engine/frozen/FrozenIndexIT.java +++ b/x-pack/plugin/frozen-indices/src/internalClusterTest/java/org/elasticsearch/index/engine/frozen/FrozenIndexIT.java @@ -9,6 +9,7 @@ package org.elasticsearch.index.engine.frozen; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.DocWriteResponse; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.search.ClosePointInTimeRequest; import org.elasticsearch.action.search.OpenPointInTimeRequest; import org.elasticsearch.action.search.SearchType; @@ -85,7 +86,7 @@ public class FrozenIndexIT extends ESIntegTestCase { final String excludeSetting = INDEX_ROUTING_EXCLUDE_GROUP_SETTING.getConcreteSettingForNamespace("_name").getKey(); updateIndexSettings(Settings.builder().put(excludeSetting, nodeNames.get(0)), "index"); - assertAcked(clusterAdmin().prepareReroute().add(new CancelAllocationCommand("index", 0, nodeNames.get(0), true))); + ClusterRerouteUtils.reroute(client(), new CancelAllocationCommand("index", 0, nodeNames.get(0), true)); assertThat(clusterAdmin().prepareHealth("index").get().getUnassignedShards(), equalTo(1)); assertThat(client().prepareDelete("index", indexResponse.getId()).get().status(), equalTo(RestStatus.OK)); @@ -107,7 +108,7 @@ public class FrozenIndexIT extends ESIntegTestCase { updateIndexSettings(Settings.builder().putNull(excludeSetting), "index"); assertThat(clusterAdmin().prepareHealth("index").get().getUnassignedShards(), equalTo(2)); - assertAcked(clusterAdmin().prepareReroute().add(new AllocateStalePrimaryAllocationCommand("index", 0, nodeNames.get(0), true))); + ClusterRerouteUtils.reroute(client(), new AllocateStalePrimaryAllocationCommand("index", 0, nodeNames.get(0), true)); ensureYellowAndNoInitializingShards("index"); diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalService.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalService.java index df546efd161e..dbc36960a823 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalService.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalService.java @@ -132,16 +132,10 @@ public class ElasticsearchInternalService implements InferenceService { ).build(); throwIfNotEmptyMap(serviceSettingsMap, name()); - var taskSettings = CustomElandModel.taskSettingsFromMap(TaskType.RERANK, taskSettingsMap); + var taskSettings = CustomElandModel.taskSettingsFromMap(taskType, taskSettingsMap); throwIfNotEmptyMap(taskSettingsMap, name()); - var model = CustomElandModel.build( - inferenceEntityId, - TaskType.RERANK, - name(), - customElandInternalServiceSettings, - taskSettings - ); + var model = CustomElandModel.build(inferenceEntityId, taskType, name(), customElandInternalServiceSettings, taskSettings); delegate.onResponse(model); } }); diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalServiceTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalServiceTests.java index e34ce410bbab..dfcfe466c2a3 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalServiceTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elasticsearch/ElasticsearchInternalServiceTests.java @@ -11,7 +11,9 @@ package org.elasticsearch.xpack.inference.services.elasticsearch; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.core.TimeValue; import org.elasticsearch.inference.ChunkedInferenceServiceResults; import org.elasticsearch.inference.ChunkingOptions; import org.elasticsearch.inference.InferenceResults; @@ -55,7 +57,6 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -63,6 +64,7 @@ import java.util.concurrent.atomic.AtomicReference; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.doAnswer; @@ -83,7 +85,7 @@ public class ElasticsearchInternalServiceTests extends ESTestCase { @After public void shutdownThreadPool() { - TestThreadPool.terminate(threadPool, 30, TimeUnit.SECONDS); + terminate(threadPool); } public void testParseRequestConfig() { @@ -290,7 +292,7 @@ public class ElasticsearchInternalServiceTests extends ESTestCase { assertEquals(returnDocs, ((CustomElandRerankTaskSettings) model.getTaskSettings()).returnDocuments()); }, e -> { fail("Model parsing failed " + e.getMessage()); }); - service.parseRequestConfig(randomInferenceEntityId, taskType, settings, Set.of(), modelListener); + service.parseRequestConfig(randomInferenceEntityId, TaskType.RERANK, settings, Set.of(), modelListener); } } @@ -332,7 +334,7 @@ public class ElasticsearchInternalServiceTests extends ESTestCase { assertEquals(Boolean.TRUE, ((CustomElandRerankTaskSettings) model.getTaskSettings()).returnDocuments()); }, e -> { fail("Model parsing failed " + e.getMessage()); }); - service.parseRequestConfig(randomInferenceEntityId, taskType, settings, Set.of(), modelListener); + service.parseRequestConfig(randomInferenceEntityId, TaskType.RERANK, settings, Set.of(), modelListener); } } @@ -671,6 +673,52 @@ public class ElasticsearchInternalServiceTests extends ESTestCase { } } + public void testParseRequestConfigEland_PreservesTaskType() { + var client = mock(Client.class); + doAnswer(invocationOnMock -> { + @SuppressWarnings("unchecked") + ActionListener listener = (ActionListener) invocationOnMock + .getArguments()[2]; + listener.onResponse( + new GetTrainedModelsAction.Response(new QueryPage<>(List.of(mock(TrainedModelConfig.class)), 1, mock(ParseField.class))) + ); + return Void.TYPE; + }).when(client).execute(any(), any(), any()); + when(client.threadPool()).thenReturn(threadPool); + + var service = createService(client); + var settings = new HashMap(); + settings.put( + ModelConfigurations.SERVICE_SETTINGS, + new HashMap<>( + Map.of( + ElasticsearchInternalServiceSettings.NUM_ALLOCATIONS, + 1, + ElasticsearchInternalServiceSettings.NUM_THREADS, + 4, + InternalServiceSettings.MODEL_ID, + "custom-model" + ) + ) + ); + + var serviceSettings = new CustomElandInternalServiceSettings(1, 4, "custom-model"); + var taskType = randomFrom(TaskType.values()); + var taskSettings = taskType == TaskType.RERANK ? CustomElandRerankTaskSettings.DEFAULT_SETTINGS : null; + var expectedModel = CustomElandModel.build( + randomInferenceEntityId, + taskType, + ElasticsearchInternalService.NAME, + serviceSettings, + taskSettings + ); + + PlainActionFuture listener = new PlainActionFuture<>(); + service.parseRequestConfig(randomInferenceEntityId, taskType, settings, Set.of(), listener); + var model = listener.actionGet(TimeValue.THIRTY_SECONDS); + assertThat(model, is(expectedModel)); + } + public void testBuildInferenceRequest() { var id = randomAlphaOfLength(5); var inputs = randomList(1, 3, () -> randomAlphaOfLength(4)); diff --git a/x-pack/plugin/mapper-unsigned-long/src/yamlRestTest/resources/rest-api-spec/test/60_collapse.yml b/x-pack/plugin/mapper-unsigned-long/src/yamlRestTest/resources/rest-api-spec/test/60_collapse.yml index 0c87424a88fe..84f162cdae94 100644 --- a/x-pack/plugin/mapper-unsigned-long/src/yamlRestTest/resources/rest-api-spec/test/60_collapse.yml +++ b/x-pack/plugin/mapper-unsigned-long/src/yamlRestTest/resources/rest-api-spec/test/60_collapse.yml @@ -1,5 +1,9 @@ setup: - + - skip: + reason: "https://github.com/elastic/elasticsearch/issues/109476" + known_issues: + - cluster_feature: "gte_v8.13.0" + fixed_by: "gte_v8.14.0" - requires: cluster_features: ["gte_v8.0.0"] reason: "collapse on unsigned_long was added in 8.0" diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportTrainedModelCacheInfoAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportTrainedModelCacheInfoAction.java index 89eb1dc45c54..f2c2b6de0e19 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportTrainedModelCacheInfoAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportTrainedModelCacheInfoAction.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.ml.action; +import org.elasticsearch.TransportVersions; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.TransportNodesAction; @@ -15,6 +16,7 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.UpdateForV9; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; @@ -67,7 +69,7 @@ public class TransportTrainedModelCacheInfoAction extends TransportNodesAction< @Override protected NodeModelCacheInfoRequest newNodeRequest(TrainedModelCacheInfoAction.Request request) { - return new NodeModelCacheInfoRequest(request); + return new NodeModelCacheInfoRequest(); } @Override @@ -85,17 +87,16 @@ public class TransportTrainedModelCacheInfoAction extends TransportNodesAction< ); } + @UpdateForV9 // this can be replaced with TransportRequest.Empty in v9 public static class NodeModelCacheInfoRequest extends TransportRequest { - TrainedModelCacheInfoAction.Request request; + NodeModelCacheInfoRequest() {} public NodeModelCacheInfoRequest(StreamInput in) throws IOException { super(in); - request = new TrainedModelCacheInfoAction.Request(in); - } - - NodeModelCacheInfoRequest(TrainedModelCacheInfoAction.Request request) { - this.request = request; + if (in.getTransportVersion().before(TransportVersions.DROP_UNUSED_NODES_REQUESTS)) { + new TrainedModelCacheInfoAction.Request(in); + } } @Override @@ -106,7 +107,9 @@ public class TransportTrainedModelCacheInfoAction extends TransportNodesAction< @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - request.writeTo(out); + if (out.getTransportVersion().before(TransportVersions.DROP_UNUSED_NODES_REQUESTS)) { + new TrainedModelCacheInfoAction.Request().writeTo(out); + } } } } diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/pytorch/process/PyTorchResultProcessor.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/pytorch/process/PyTorchResultProcessor.java index 5636762871b2..87fad19ab87f 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/pytorch/process/PyTorchResultProcessor.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/inference/pytorch/process/PyTorchResultProcessor.java @@ -141,6 +141,9 @@ public class PyTorchResultProcessor { } private void notifyAndClearPendingResults(ErrorResult errorResult) { + if (pendingResults.size() > 0) { + logger.warn(format("[%s] clearing [%d] requests pending results", modelId, pendingResults.size())); + } pendingResults.forEach( (id, pendingResult) -> pendingResult.listener.onResponse(new PyTorchResult(id, null, null, null, null, null, errorResult)) ); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/process/AbstractProcessWorkerExecutorService.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/process/AbstractProcessWorkerExecutorService.java index dee608e69f5b..debe6586e453 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/process/AbstractProcessWorkerExecutorService.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/process/AbstractProcessWorkerExecutorService.java @@ -26,6 +26,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import static org.elasticsearch.core.Strings.format; + /** * A worker service that executes runnables sequentially in * a single worker thread. @@ -139,6 +141,10 @@ public abstract class AbstractProcessWorkerExecutorService e assert isShutdown() : "Queue runnables should only be drained and notified after the worker is shutdown"; if (queue.isEmpty() == false) { + logger.warn( + format("[%s] notifying [%d] queued requests that have not been processed before shutdown", processName, queue.size()) + ); + List notExecuted = new ArrayList<>(); queue.drainTo(notExecuted); diff --git a/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java b/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java index 383598c804f7..9d2168267bb8 100644 --- a/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java +++ b/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java @@ -144,6 +144,7 @@ public class SamlServiceProviderMetadataIT extends ESRestTestCase { } else { if (randomBoolean()) { http.sendResponseHeaders(randomFrom(404, 401, 403, 500), 0); + http.getResponseBody().close(); } else { sendXmlContent("not valid xml", http); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java index 55be659512c5..dd2377ec773c 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java @@ -9,7 +9,6 @@ package org.elasticsearch.xpack.security.profile; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.lucene.search.TotalHits; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.ExceptionsHelper; @@ -40,6 +39,7 @@ import org.elasticsearch.client.internal.OriginSettingClient; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.xcontent.XContentHelper; @@ -265,11 +265,7 @@ public class ProfileService { public void suggestProfile(SuggestProfilesRequest request, TaskId parentTaskId, ActionListener listener) { tryFreezeAndCheckIndex(listener.map(response -> { assert response == null : "only null response can reach here"; - return new SuggestProfilesResponse( - new SuggestProfilesResponse.ProfileHit[] {}, - 0, - new TotalHits(0, TotalHits.Relation.EQUAL_TO) - ); + return new SuggestProfilesResponse(new SuggestProfilesResponse.ProfileHit[] {}, 0, Lucene.TOTAL_HITS_EQUAL_TO_ZERO); }), SEARCH_SHARDS).ifPresent(frozenProfileIndex -> { final SearchRequest searchRequest = buildSearchRequestForSuggest(request, parentTaskId); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticatorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticatorTests.java index 16c7b39fa695..83f09bad0d27 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticatorTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/saml/SamlAuthenticatorTests.java @@ -592,17 +592,23 @@ public class SamlAuthenticatorTests extends SamlResponseHandlerTests { } public void testExpiredAuthnStatementSessionIsRejected() throws Exception { - Instant now = clock.instant(); - String xml = getSimpleResponseAsString(now); + final Instant now = clock.instant(); + final int sessionExpirySeconds = 60; + final Instant subjectConfirmationValidUntil = now.plusSeconds(500); + final Instant sessionValidUntil = now.plusSeconds(sessionExpirySeconds); + final String xml = SamlUtils.getXmlContent( + getSimpleResponse(now, randomId(), randomId(), subjectConfirmationValidUntil, sessionValidUntil), + false + ); SamlToken token = token(signResponse(xml)); assertThat(authenticator.authenticate(token), notNullValue()); // and still valid if we advance partway through the session expiry time - clock.fastForwardSeconds(30); + clock.fastForwardSeconds(sessionExpirySeconds / 2); assertThat(authenticator.authenticate(token), notNullValue()); // and still valid if we advance past the expiry time, but allow for clock skew - clock.fastForwardSeconds((int) (30 + maxSkew.seconds() / 2)); + clock.fastForwardSeconds((int) (sessionExpirySeconds / 2 + maxSkew.seconds() / 2)); assertThat(authenticator.authenticate(token), notNullValue()); // but fails once we get past the clock skew allowance @@ -1442,8 +1448,8 @@ public class SamlAuthenticatorTests extends SamlResponseHandlerTests { } private Response getSimpleResponse(Instant now, String nameId, String sessionindex) { - Instant subjectConfirmationValidUntil = now.plusSeconds(120); - Instant sessionValidUntil = now.plusSeconds(60); + Instant subjectConfirmationValidUntil = now.plusSeconds(500); + Instant sessionValidUntil = now.plusSeconds(300); return getSimpleResponse(now, nameId, sessionindex, subjectConfirmationValidUntil, sessionValidUntil); } @@ -1565,7 +1571,7 @@ public class SamlAuthenticatorTests extends SamlResponseHandlerTests { String nameId, String sessionindex ) { - Instant validUntil = now.plusSeconds(30); + Instant validUntil = now.plusSeconds(300); String xml = " assertNotNull("expected to have candidate nodes chosen for task", candidates.get())); // Check that the node that is not shut down is the only candidate diff --git a/x-pack/plugin/slm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/slm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index 3787761a2b28..a64df7f871d9 100644 --- a/x-pack/plugin/slm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/slm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.slm; import org.elasticsearch.action.ActionFuture; +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; @@ -248,7 +249,7 @@ public class SLMSnapshotBlockingIntegTests extends AbstractSnapshotIntegTestCase // Check that the snapshot created by the policy has been removed by retention assertBusy(() -> { // Trigger a cluster state update so that it re-checks for a snapshot in progress - clusterAdmin().prepareReroute().get(); + ClusterRerouteUtils.reroute(client()); logger.info("--> waiting for snapshot to be deleted"); try { SnapshotsStatusResponse s = getSnapshotStatus(completedSnapshotName); diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/10_basic.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/10_basic.yml index ab0261d91663..1c95e961d053 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/10_basic.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/10_basic.yml @@ -309,12 +309,12 @@ setup: - match: {values.0: [1, 44, "green"]} --- -"Test Mixed Input Params": +"Test Unnamed Input Params": - do: esql.query: body: query: 'from test | eval x = ?, y = ?, z = ?, t = ?, u = ?, v = ? | keep x, y, z, t, u, v | limit 3' - params: [{"value": 1, "type": "keyword"}, {"value": 2, "type": "double"}, null, true, 123, {"value": 123, "type": "long"}] + params: ["1", 2.0, null, true, 123, 1674835275193] - length: {columns: 6} - match: {columns.0.name: "x"} @@ -330,9 +330,44 @@ setup: - match: {columns.5.name: "v"} - match: {columns.5.type: "long"} - length: {values: 3} - - match: {values.0: ["1",2.0,null,true,123,123]} - - match: {values.1: ["1",2.0,null,true,123,123]} - - match: {values.2: ["1",2.0,null,true,123,123]} + - match: {values.0: ["1",2.0,null,true,123,1674835275193]} + - match: {values.1: ["1",2.0,null,true,123,1674835275193]} + - match: {values.2: ["1",2.0,null,true,123,1674835275193]} + +--- +"Test Named Input Params": + - requires: + test_runner_features: [ capabilities ] + capabilities: + - method: POST + path: /_query + parameters: [ ] + capabilities: [ named_positional_parameter ] + reason: "named or positional parameters" + + - do: + esql.query: + body: + query: 'from test | eval x = ?, y = ?, z = ?, t = ?, u = ?, v = ? | keep x, y, z, t, u, v | limit 3' + params: [{"n1" : "1"}, {"n2" : 2.0}, {"n3" : null}, {"n4" : true}, {"n5" : 123}, {"n6": 1674835275193}] + + - length: {columns: 6} + - match: {columns.0.name: "x"} + - match: {columns.0.type: "keyword"} + - match: {columns.1.name: "y"} + - match: {columns.1.type: "double"} + - match: {columns.2.name: "z"} + - match: {columns.2.type: "null"} + - match: {columns.3.name: "t"} + - match: {columns.3.type: "boolean"} + - match: {columns.4.name: "u"} + - match: {columns.4.type: "integer"} + - match: {columns.5.name: "v"} + - match: {columns.5.type: "long"} + - length: {values: 3} + - match: {values.0: ["1",2.0,null,true,123,1674835275193]} + - match: {values.1: ["1",2.0,null,true,123,1674835275193]} + - match: {values.2: ["1",2.0,null,true,123,1674835275193]} --- version is not allowed: diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/150_lookup.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/150_lookup.yml index dcffca2f28fb..5f76954e57c8 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/150_lookup.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/150_lookup.yml @@ -38,7 +38,7 @@ basic: - method: POST path: /_query parameters: [] - capabilities: [lookup_command] + capabilities: [lookup_command, tables_types] reason: "uses LOOKUP" - do: @@ -48,8 +48,8 @@ basic: columnar: true tables: colors: - "color:keyword": ["red", "green", "blue"] - "rgb:integer": [16711680, 65280, 255] + color: { keyword: ["red", "green", "blue"] } + rgb: { integer: [16711680, 65280, 255] } - match: {columns.0.name: "color"} - match: {columns.0.type: "keyword"} @@ -66,7 +66,7 @@ read multivalue keyword: - method: POST path: /_query parameters: [] - capabilities: [lookup_command] + capabilities: [lookup_command, tables_types] reason: "uses LOOKUP" - do: @@ -76,11 +76,12 @@ read multivalue keyword: columnar: true tables: color_associations: - "color:keyword": ["red", "green", "blue"] - "association:keyword": - - ["love", "passion", "blood", "happiness"] - - ["nature", "healing", "health", "youth"] - - ["serenity", "wisdom", "ocean", "sky"] + color: {keyword: ["red", "green", "blue"] } + association: + keyword: + - ["love", "passion", "blood", "happiness"] + - ["nature", "healing", "health", "youth"] + - ["serenity", "wisdom", "ocean", "sky"] - match: {columns.0.name: "color"} - match: {columns.0.type: "keyword"} @@ -97,7 +98,7 @@ keyword matches text: - method: POST path: /_query parameters: [] - capabilities: [lookup_command] + capabilities: [lookup_command, tables_types] reason: "uses LOOKUP" - do: @@ -125,8 +126,8 @@ keyword matches text: columnar: true tables: colors: - "color:keyword": ["red", "green", "blue"] - "rgb:integer": [16711680, 65280, 255] + color: { keyword: ["red", "green", "blue"] } + rgb: { integer: [16711680, 65280, 255] } - match: {columns.0.name: "color"} - match: {columns.0.type: "text"} @@ -135,28 +136,6 @@ keyword matches text: - match: {values.0: ["red"]} - match: {values.1: [16711680]} ---- -duplicate column names in table: - - requires: - test_runner_features: [capabilities] - capabilities: - - method: POST - path: /_query - parameters: [] - capabilities: [lookup_command] - reason: "uses LOOKUP" - - - do: - catch: /duplicate column name \[color\]/ - esql.query: - body: - query: 'FROM test | LOOKUP colors ON color | SORT time | KEEP color, rgb | LIMIT 2' - columnar: true - tables: - colors: - "color:keyword": ["red", "green", "blue"] - "color:integer": [16711680, 65280, 255] - --- duplicate keys: - requires: @@ -165,7 +144,7 @@ duplicate keys: - method: POST path: /_query parameters: [] - capabilities: [lookup_command] + capabilities: [lookup_command, tables_types] reason: "uses LOOKUP" - do: @@ -177,8 +156,8 @@ duplicate keys: columnar: true tables: colors: - "color:keyword": ["red", "red", "blue"] - "rgb:integer": [16711680, 65280, 255] + color: {keyword: ["red", "red", "blue"] } + rgb: {integer: [16711680, 65280, 255] } --- multivalued keys: @@ -188,7 +167,7 @@ multivalued keys: - method: POST path: /_query parameters: [] - capabilities: [lookup_command] + capabilities: [lookup_command, tables_types] reason: "uses LOOKUP" - do: @@ -200,8 +179,8 @@ multivalued keys: columnar: true tables: colors: - "color:keyword": [["red", "blue"], "white", "blue"] - "rgb:integer": [16711680, 65280, 255] + color: { keyword: [["red", "blue"], "white", "blue"] } + rgb: { integer: [16711680, 65280, 255] } --- index named lookup still works: @@ -230,7 +209,7 @@ on function: - method: POST path: /_query parameters: [] - capabilities: [lookup_command] + capabilities: [lookup_command, tables_types] reason: "uses LOOKUP" - do: @@ -241,5 +220,5 @@ on function: columnar: true tables: colors: - "color:keyword": ["red", "green", "blue"] - "rgb:integer": [16711680, 65280, 255] + color: { keyword: ["red", "green", "blue"] } + rgb: { integer: [16711680, 65280, 255] }