Merge remote-tracking branch 'es/master' into ccr

* es/master:
  Add Index UUID to `/_stats` Response (#31871)
  Painless: Move and Rename Several Methods in the lookup package (#32105)
  Bypass highlight query terms extraction on empty fields (#32090)
  Switch non-x-pack to new style requests (#32106)
  [Rollup] Add new capabilities endpoint for concrete rollup indices (#30401)
  Revert "[test] disable packaging tests for suse boxes"
  SQL: allow LEFT and RIGHT as function names (#32066)
  DOCS: put LIMIT 10 to the SQL query (#32065)
  [test] turn on host io cache for opensuse (#32053)
  Tweaked Elasticsearch Service links for SEO
This commit is contained in:
Martijn van Groningen 2018-07-17 07:36:34 +02:00
commit d0c9cf26a9
No known key found for this signature in database
GPG Key ID: AB236F4FCF2AF12A
74 changed files with 2577 additions and 1288 deletions

5
Vagrantfile vendored
View File

@ -115,6 +115,11 @@ Vagrant.configure(2) do |config|
'opensuse-42'.tap do |box|
config.vm.define box, define_opts do |config|
config.vm.box = 'elastic/opensuse-42-x86_64'
# https://github.com/elastic/elasticsearch/issues/30295
config.vm.provider 'virtualbox' do |vbox|
vbox.customize ['storagectl', :id, '--name', 'SATA Controller', '--hostiocache', 'on']
end
suse_common config, box
end
end

View File

@ -526,11 +526,7 @@ class VagrantTestPlugin implements Plugin<Project> {
project.gradle.removeListener(batsPackagingReproListener)
}
if (project.extensions.esvagrant.boxes.contains(box)) {
// these tests are temporarily disabled for suse boxes while we debug an issue
// https://github.com/elastic/elasticsearch/issues/30295
if (box.equals("opensuse-42") == false && box.equals("sles-12") == false) {
packagingTest.dependsOn(batsPackagingTest)
}
packagingTest.dependsOn(batsPackagingTest)
}
}
@ -569,11 +565,7 @@ class VagrantTestPlugin implements Plugin<Project> {
project.gradle.removeListener(javaPackagingReproListener)
}
if (project.extensions.esvagrant.boxes.contains(box)) {
// these tests are temporarily disabled for suse boxes while we debug an issue
// https://github.com/elastic/elasticsearch/issues/30295
if (box.equals("opensuse-42") == false && box.equals("sles-12") == false) {
packagingTest.dependsOn(javaPackagingTest)
}
packagingTest.dependsOn(javaPackagingTest)
}
/*

View File

@ -106,10 +106,11 @@ With that out of the way, let's get started with the fun part...
[TIP]
==============
You can skip installation completely by using our hosted
Elasticsearch Service on https://www.elastic.co/cloud[Elastic Cloud], which is
available on AWS and GCP. You can
https://www.elastic.co/cloud/elasticsearch-service/signup[try out the hosted service] for free.
You can skip having to install Elasticsearch by using our
https://www.elastic.co/cloud/elasticsearch-service[hosted Elasticsearch Service]
on Elastic Cloud. The Elasticsearch Service is available on both AWS and GCP.
https://www.elastic.co/cloud/elasticsearch-service/signup[Try out the
Elasticsearch Service for free].
==============
Elasticsearch requires at least Java 8. Specifically as of this writing, it is recommended that you use the Oracle JDK version {jdk}. Java installation varies from platform to platform so we won't go into those details here. Oracle's recommended installation documentation can be found on http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html[Oracle's website]. Suffice to say, before you install Elasticsearch, please check your Java version first by running (and then install/upgrade accordingly if needed):
@ -1121,7 +1122,7 @@ In SQL, the above aggregation is similar in concept to:
[source,sh]
--------------------------------------------------
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC LIMIT 10;
--------------------------------------------------
And the response (partially shown):

View File

@ -19,8 +19,8 @@
package org.elasticsearch.painless;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import java.util.Objects;
@ -465,8 +465,9 @@ public final class AnalyzerCaster {
(actual.isAssignableFrom(expected) && explicit)) {
return PainlessCast.standard(actual, expected, explicit);
} else {
throw location.createError(new ClassCastException(
"Cannot cast from [" + PainlessLookup.ClassToName(actual) + "] to [" + PainlessLookup.ClassToName(expected) + "]."));
throw location.createError(new ClassCastException("Cannot cast from " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(actual) + "] to " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]."));
}
}

View File

@ -19,9 +19,10 @@
package org.elasticsearch.painless;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import java.lang.invoke.CallSite;
@ -302,7 +303,7 @@ public final class Def {
nestedType,
0,
DefBootstrap.REFERENCE,
PainlessLookup.ClassToName(interfaceType));
PainlessLookupUtility.anyTypeToPainlessTypeName(interfaceType));
filter = nested.dynamicInvoker();
} else {
throw new AssertionError();
@ -347,7 +348,7 @@ public final class Def {
PainlessMethod interfaceMethod = painlessLookup.getPainlessStructFromJavaClass(clazz).functionalMethod;
if (interfaceMethod == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
"to [" + PainlessLookup.ClassToName(clazz) + "], not a functional interface");
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(clazz) + "], not a functional interface");
}
int arity = interfaceMethod.arguments.size() + captures.length;
final MethodHandle handle;

View File

@ -21,6 +21,7 @@ package org.elasticsearch.painless;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.objectweb.asm.Type;
@ -168,7 +169,7 @@ public class FunctionRef {
PainlessMethod method = painlessLookup.getPainlessStructFromJavaClass(expected).functionalMethod;
if (method == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
"to [" + PainlessLookup.ClassToName(expected) + "], not a functional interface");
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface");
}
// lookup requested method

View File

@ -19,10 +19,11 @@
package org.elasticsearch.painless;
import org.elasticsearch.painless.ScriptClassInfo.MethodArgument;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.ScriptClassInfo.MethodArgument;
import java.util.Arrays;
import java.util.Collection;
@ -292,7 +293,7 @@ public final class Locals {
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("Variable[type=").append(PainlessLookup.ClassToName(clazz));
b.append("Variable[type=").append(PainlessLookupUtility.anyTypeToPainlessTypeName(clazz));
b.append(",name=").append(name);
b.append(",slot=").append(slot);
if (readonly) {

View File

@ -20,6 +20,7 @@
package org.elasticsearch.painless;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
@ -182,7 +183,7 @@ public class ScriptClassInfo {
private static Class<?> definitionTypeForClass(PainlessLookup painlessLookup, Class<?> type,
Function<Class<?>, String> unknownErrorMessageSource) {
type = PainlessLookup.ObjectClassTodefClass(type);
type = PainlessLookupUtility.javaObjectTypeToPainlessDefType(type);
Class<?> componentType = type;
while (componentType.isArray()) {

View File

@ -23,8 +23,8 @@ import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.LexerNoViableAltException;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.lookup.PainlessLookup;
/**
* A lexer that is customized for painless. It:

View File

@ -19,7 +19,6 @@
package org.elasticsearch.painless.lookup;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@ -30,154 +29,6 @@ import java.util.Map;
*/
public final class PainlessLookup {
public static Class<?> getBoxedType(Class<?> clazz) {
if (clazz == boolean.class) {
return Boolean.class;
} else if (clazz == byte.class) {
return Byte.class;
} else if (clazz == short.class) {
return Short.class;
} else if (clazz == char.class) {
return Character.class;
} else if (clazz == int.class) {
return Integer.class;
} else if (clazz == long.class) {
return Long.class;
} else if (clazz == float.class) {
return Float.class;
} else if (clazz == double.class) {
return Double.class;
}
return clazz;
}
public static Class<?> getUnboxedype(Class<?> clazz) {
if (clazz == Boolean.class) {
return boolean.class;
} else if (clazz == Byte.class) {
return byte.class;
} else if (clazz == Short.class) {
return short.class;
} else if (clazz == Character.class) {
return char.class;
} else if (clazz == Integer.class) {
return int.class;
} else if (clazz == Long.class) {
return long.class;
} else if (clazz == Float.class) {
return float.class;
} else if (clazz == Double.class) {
return double.class;
}
return clazz;
}
public static boolean isConstantType(Class<?> clazz) {
return clazz == boolean.class ||
clazz == byte.class ||
clazz == short.class ||
clazz == char.class ||
clazz == int.class ||
clazz == long.class ||
clazz == float.class ||
clazz == double.class ||
clazz == String.class;
}
public Class<?> getClassFromBinaryName(String painlessType) {
return painlessTypesToJavaClasses.get(painlessType.replace('$', '.'));
}
public static Class<?> ObjectClassTodefClass(Class<?> clazz) {
if (clazz.isArray()) {
Class<?> component = clazz.getComponentType();
int dimensions = 1;
while (component.isArray()) {
component = component.getComponentType();
++dimensions;
}
if (component == Object.class) {
char[] braces = new char[dimensions];
Arrays.fill(braces, '[');
String descriptor = new String(braces) + org.objectweb.asm.Type.getType(def.class).getDescriptor();
org.objectweb.asm.Type type = org.objectweb.asm.Type.getType(descriptor);
try {
return Class.forName(type.getInternalName().replace('/', '.'));
} catch (ClassNotFoundException exception) {
throw new IllegalStateException("internal error", exception);
}
}
} else if (clazz == Object.class) {
return def.class;
}
return clazz;
}
public static Class<?> defClassToObjectClass(Class<?> clazz) {
if (clazz.isArray()) {
Class<?> component = clazz.getComponentType();
int dimensions = 1;
while (component.isArray()) {
component = component.getComponentType();
++dimensions;
}
if (component == def.class) {
char[] braces = new char[dimensions];
Arrays.fill(braces, '[');
String descriptor = new String(braces) + org.objectweb.asm.Type.getType(Object.class).getDescriptor();
org.objectweb.asm.Type type = org.objectweb.asm.Type.getType(descriptor);
try {
return Class.forName(type.getInternalName().replace('/', '.'));
} catch (ClassNotFoundException exception) {
throw new IllegalStateException("internal error", exception);
}
}
} else if (clazz == def.class) {
return Object.class;
}
return clazz;
}
public static String ClassToName(Class<?> clazz) {
if (clazz.isLocalClass() || clazz.isAnonymousClass()) {
return null;
} else if (clazz.isArray()) {
Class<?> component = clazz.getComponentType();
int dimensions = 1;
while (component.isArray()) {
component = component.getComponentType();
++dimensions;
}
if (component == def.class) {
StringBuilder builder = new StringBuilder(def.class.getSimpleName());
for (int dimension = 0; dimension < dimensions; dimension++) {
builder.append("[]");
}
return builder.toString();
}
} else if (clazz == def.class) {
return def.class.getSimpleName();
}
return clazz.getCanonicalName().replace('$', '.');
}
public Collection<PainlessClass> getStructs() {
return javaClassesToPainlessStructs.values();
}
@ -190,6 +41,10 @@ public final class PainlessLookup {
this.javaClassesToPainlessStructs = Collections.unmodifiableMap(javaClassesToPainlessStructs);
}
public Class<?> getClassFromBinaryName(String painlessType) {
return painlessTypesToJavaClasses.get(painlessType.replace('$', '.'));
}
public boolean isSimplePainlessType(String painlessType) {
return painlessTypesToJavaClasses.containsKey(painlessType);
}
@ -199,59 +54,6 @@ public final class PainlessLookup {
}
public Class<?> getJavaClassFromPainlessType(String painlessType) {
Class<?> javaClass = painlessTypesToJavaClasses.get(painlessType);
if (javaClass != null) {
return javaClass;
}
int arrayDimensions = 0;
int arrayIndex = painlessType.indexOf('[');
if (arrayIndex != -1) {
int length = painlessType.length();
while (arrayIndex < length) {
if (painlessType.charAt(arrayIndex) == '[' && ++arrayIndex < length && painlessType.charAt(arrayIndex++) == ']') {
++arrayDimensions;
} else {
throw new IllegalArgumentException("invalid painless type [" + painlessType + "].");
}
}
painlessType = painlessType.substring(0, painlessType.indexOf('['));
javaClass = painlessTypesToJavaClasses.get(painlessType);
char braces[] = new char[arrayDimensions];
Arrays.fill(braces, '[');
String descriptor = new String(braces);
if (javaClass == boolean.class) {
descriptor += "Z";
} else if (javaClass == byte.class) {
descriptor += "B";
} else if (javaClass == short.class) {
descriptor += "S";
} else if (javaClass == char.class) {
descriptor += "C";
} else if (javaClass == int.class) {
descriptor += "I";
} else if (javaClass == long.class) {
descriptor += "J";
} else if (javaClass == float.class) {
descriptor += "F";
} else if (javaClass == double.class) {
descriptor += "D";
} else {
descriptor += "L" + javaClass.getName() + ";";
}
try {
return Class.forName(descriptor);
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException("invalid painless type [" + painlessType + "]", cnfe);
}
}
throw new IllegalArgumentException("invalid painless type [" + painlessType + "]");
return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessType, painlessTypesToJavaClasses);
}
}

View File

@ -30,7 +30,6 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -279,7 +278,7 @@ public class PainlessLookupBuilder {
Class<?> painlessParameterClass = getJavaClassFromPainlessType(painlessParameterTypeName);
painlessParametersTypes.add(painlessParameterClass);
javaClassParameters[parameterCount] = PainlessLookup.defClassToObjectClass(painlessParameterClass);
javaClassParameters[parameterCount] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessParameterClass);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("struct not defined for constructor parameter [" + painlessParameterTypeName + "] " +
"with owner struct [" + ownerStructName + "] and constructor parameters " +
@ -364,7 +363,8 @@ public class PainlessLookupBuilder {
Class<?> painlessParameterClass = getJavaClassFromPainlessType(painlessParameterTypeName);
painlessParametersTypes.add(painlessParameterClass);
javaClassParameters[parameterCount + augmentedOffset] = PainlessLookup.defClassToObjectClass(painlessParameterClass);
javaClassParameters[parameterCount + augmentedOffset] =
PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessParameterClass);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("struct not defined for method parameter [" + painlessParameterTypeName + "] " +
"with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " +
@ -393,7 +393,7 @@ public class PainlessLookupBuilder {
"and parameters " + whitelistMethod.painlessParameterTypeNames, iae);
}
if (javaMethod.getReturnType() != PainlessLookup.defClassToObjectClass(painlessReturnClass)) {
if (javaMethod.getReturnType() != PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessReturnClass)) {
throw new IllegalArgumentException("specified return type class [" + painlessReturnClass + "] " +
"does not match the return type class [" + javaMethod.getReturnType() + "] for the " +
"method with name [" + whitelistMethod.javaMethodName + "] " +
@ -711,64 +711,11 @@ public class PainlessLookupBuilder {
return painless;
}
public Class<?> getJavaClassFromPainlessType(String painlessType) {
Class<?> javaClass = painlessTypesToJavaClasses.get(painlessType);
if (javaClass != null) {
return javaClass;
}
int arrayDimensions = 0;
int arrayIndex = painlessType.indexOf('[');
if (arrayIndex != -1) {
int length = painlessType.length();
while (arrayIndex < length) {
if (painlessType.charAt(arrayIndex) == '[' && ++arrayIndex < length && painlessType.charAt(arrayIndex++) == ']') {
++arrayDimensions;
} else {
throw new IllegalArgumentException("invalid painless type [" + painlessType + "].");
}
}
painlessType = painlessType.substring(0, painlessType.indexOf('['));
javaClass = painlessTypesToJavaClasses.get(painlessType);
char braces[] = new char[arrayDimensions];
Arrays.fill(braces, '[');
String descriptor = new String(braces);
if (javaClass == boolean.class) {
descriptor += "Z";
} else if (javaClass == byte.class) {
descriptor += "B";
} else if (javaClass == short.class) {
descriptor += "S";
} else if (javaClass == char.class) {
descriptor += "C";
} else if (javaClass == int.class) {
descriptor += "I";
} else if (javaClass == long.class) {
descriptor += "J";
} else if (javaClass == float.class) {
descriptor += "F";
} else if (javaClass == double.class) {
descriptor += "D";
} else {
descriptor += "L" + javaClass.getName() + ";";
}
try {
return Class.forName(descriptor);
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException("invalid painless type [" + painlessType + "]", cnfe);
}
}
throw new IllegalArgumentException("invalid painless type [" + painlessType + "]");
}
public PainlessLookup build() {
return new PainlessLookup(painlessTypesToJavaClasses, javaClassesToPainlessStructs);
}
public Class<?> getJavaClassFromPainlessType(String painlessType) {
return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessType, painlessTypesToJavaClasses);
}
}

View File

@ -0,0 +1,284 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.painless.lookup;
import org.objectweb.asm.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
/**
* This class contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other classes within
* Painless for conversion between type names and types along with some other various utility methods.
*
* The following terminology is used for variable names throughout the lookup package:
*
* - javaClass (Class) - a java class including def and excluding array type java classes
* - javaClassName (String) - the fully qualified java class name for a javaClass
* - painlessClassName (String) - the fully qualified painless name or imported painless name for a painlessClass
* - anyClassName (String) - either a javaClassName or a painlessClassName
* - javaType (Class) - a java class excluding def and array type java classes
* - painlessType (Class) - a java class including def and array type java classes
* - javaTypeName (String) - the fully qualified java Type name for a javaType
* - painlessTypeName (String) - the fully qualified painless name or imported painless name for a painlessType
* - anyTypeName (String) - either a javaTypeName or a painlessTypeName
* - painlessClass (PainlessClass) - a painless class object
*
* Under ambiguous circumstances most variable names are prefixed with asm, java, or painless.
* If the variable name is the same for asm, java, and painless, no prefix is used.
*/
public final class PainlessLookupUtility {
public static Class<?> javaObjectTypeToPainlessDefType(Class<?> javaType) {
if (javaType.isArray()) {
Class<?> javaTypeComponent = javaType.getComponentType();
int arrayDimensions = 1;
while (javaTypeComponent.isArray()) {
javaTypeComponent = javaTypeComponent.getComponentType();
++arrayDimensions;
}
if (javaTypeComponent == Object.class) {
char[] asmDescriptorBraces = new char[arrayDimensions];
Arrays.fill(asmDescriptorBraces, '[');
String asmDescriptor = new String(asmDescriptorBraces) + Type.getType(def.class).getDescriptor();
Type asmType = Type.getType(asmDescriptor);
try {
return Class.forName(asmType.getInternalName().replace('/', '.'));
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException("internal error", cnfe);
}
}
} else if (javaType == Object.class) {
return def.class;
}
return javaType;
}
public static Class<?> painlessDefTypeToJavaObjectType(Class<?> painlessType) {
if (painlessType.isArray()) {
Class<?> painlessTypeComponent = painlessType.getComponentType();
int arrayDimensions = 1;
while (painlessTypeComponent.isArray()) {
painlessTypeComponent = painlessTypeComponent.getComponentType();
++arrayDimensions;
}
if (painlessTypeComponent == def.class) {
char[] asmDescriptorBraces = new char[arrayDimensions];
Arrays.fill(asmDescriptorBraces, '[');
String asmDescriptor = new String(asmDescriptorBraces) + Type.getType(Object.class).getDescriptor();
Type asmType = Type.getType(asmDescriptor);
try {
return Class.forName(asmType.getInternalName().replace('/', '.'));
} catch (ClassNotFoundException exception) {
throw new IllegalStateException("internal error", exception);
}
}
} else if (painlessType == def.class) {
return Object.class;
}
return painlessType;
}
public static String anyTypeNameToPainlessTypeName(String anyTypeName) {
return anyTypeName.replace(def.class.getName(), DEF_PAINLESS_CLASS_NAME).replace('$', '.');
}
public static String anyTypeToPainlessTypeName(Class<?> anyType) {
if (anyType.isLocalClass() || anyType.isAnonymousClass()) {
return null;
} else if (anyType.isArray()) {
Class<?> anyTypeComponent = anyType.getComponentType();
int arrayDimensions = 1;
while (anyTypeComponent.isArray()) {
anyTypeComponent = anyTypeComponent.getComponentType();
++arrayDimensions;
}
if (anyTypeComponent == def.class) {
StringBuilder painlessDefTypeNameArrayBuilder = new StringBuilder(DEF_PAINLESS_CLASS_NAME);
for (int dimension = 0; dimension < arrayDimensions; dimension++) {
painlessDefTypeNameArrayBuilder.append("[]");
}
return painlessDefTypeNameArrayBuilder.toString();
}
} else if (anyType == def.class) {
return DEF_PAINLESS_CLASS_NAME;
}
return anyType.getCanonicalName().replace('$', '.');
}
public static Class<?> painlessTypeNameToPainlessType(String painlessTypeName, Map<String, Class<?>> painlessClassNamesToJavaClasses) {
Class<?> javaClass = painlessClassNamesToJavaClasses.get(painlessTypeName);
if (javaClass != null) {
return javaClass;
}
int arrayDimensions = 0;
int arrayIndex = painlessTypeName.indexOf('[');
if (arrayIndex != -1) {
int painlessTypeNameLength = painlessTypeName.length();
while (arrayIndex < painlessTypeNameLength) {
if (painlessTypeName.charAt(arrayIndex) == '[' &&
++arrayIndex < painlessTypeNameLength &&
painlessTypeName.charAt(arrayIndex++) == ']') {
++arrayDimensions;
} else {
throw new IllegalArgumentException("invalid painless type [" + painlessTypeName + "].");
}
}
painlessTypeName = painlessTypeName.substring(0, painlessTypeName.indexOf('['));
javaClass = painlessClassNamesToJavaClasses.get(painlessTypeName);
char javaDescriptorBraces[] = new char[arrayDimensions];
Arrays.fill(javaDescriptorBraces, '[');
String javaDescriptor = new String(javaDescriptorBraces);
if (javaClass == boolean.class) {
javaDescriptor += "Z";
} else if (javaClass == byte.class) {
javaDescriptor += "B";
} else if (javaClass == short.class) {
javaDescriptor += "S";
} else if (javaClass == char.class) {
javaDescriptor += "C";
} else if (javaClass == int.class) {
javaDescriptor += "I";
} else if (javaClass == long.class) {
javaDescriptor += "J";
} else if (javaClass == float.class) {
javaDescriptor += "F";
} else if (javaClass == double.class) {
javaDescriptor += "D";
} else {
javaDescriptor += "L" + javaClass.getName() + ";";
}
try {
return Class.forName(javaDescriptor);
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException("painless type [" + painlessTypeName + "] not found", cnfe);
}
}
throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found");
}
public static void validatePainlessType(Class<?> painlessType, Collection<Class<?>> javaClasses) {
String painlessTypeName = anyTypeNameToPainlessTypeName(painlessType.getName());
while (painlessType.getComponentType() != null) {
painlessType = painlessType.getComponentType();
}
if (javaClasses.contains(painlessType) == false) {
throw new IllegalStateException("painless type [" + painlessTypeName + "] not found");
}
}
public static String buildPainlessMethodKey(String methodName, int methodArity) {
return methodName + "/" + methodArity;
}
public static String buildPainlessFieldKey(String fieldName) {
return fieldName;
}
public static Class<?> getBoxedAnyType(Class<?> anyType) {
if (anyType == boolean.class) {
return Boolean.class;
} else if (anyType == byte.class) {
return Byte.class;
} else if (anyType == short.class) {
return Short.class;
} else if (anyType == char.class) {
return Character.class;
} else if (anyType == int.class) {
return Integer.class;
} else if (anyType == long.class) {
return Long.class;
} else if (anyType == float.class) {
return Float.class;
} else if (anyType == double.class) {
return Double.class;
}
return anyType;
}
public static Class<?> getUnboxedAnyType(Class<?> anyType) {
if (anyType == Boolean.class) {
return boolean.class;
} else if (anyType == Byte.class) {
return byte.class;
} else if (anyType == Short.class) {
return short.class;
} else if (anyType == Character.class) {
return char.class;
} else if (anyType == Integer.class) {
return int.class;
} else if (anyType == Long.class) {
return long.class;
} else if (anyType == Float.class) {
return float.class;
} else if (anyType == Double.class) {
return double.class;
}
return anyType;
}
public static boolean isAnyTypeConstant(Class<?> anyType) {
return anyType == boolean.class ||
anyType == byte.class ||
anyType == short.class ||
anyType == char.class ||
anyType == int.class ||
anyType == long.class ||
anyType == float.class ||
anyType == double.class ||
anyType == String.class;
}
public static final String DEF_PAINLESS_CLASS_NAME = def.class.getSimpleName();
public static final String CONSTRUCTOR_ANY_NAME = "<init>";
private PainlessLookupUtility() {
}
}

View File

@ -69,21 +69,21 @@ public class PainlessMethod {
params = new Class<?>[1 + arguments.size()];
params[0] = augmentation;
for (int i = 0; i < arguments.size(); i++) {
params[i + 1] = PainlessLookup.defClassToObjectClass(arguments.get(i));
params[i + 1] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
}
returnValue = PainlessLookup.defClassToObjectClass(rtn);
returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn);
} else if (Modifier.isStatic(modifiers)) {
// static method: straightforward copy
params = new Class<?>[arguments.size()];
for (int i = 0; i < arguments.size(); i++) {
params[i] = PainlessLookup.defClassToObjectClass(arguments.get(i));
params[i] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
}
returnValue = PainlessLookup.defClassToObjectClass(rtn);
returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn);
} else if ("<init>".equals(name)) {
// constructor: returns the owner class
params = new Class<?>[arguments.size()];
for (int i = 0; i < arguments.size(); i++) {
params[i] = PainlessLookup.defClassToObjectClass(arguments.get(i));
params[i] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
}
returnValue = owner.clazz;
} else {
@ -91,9 +91,9 @@ public class PainlessMethod {
params = new Class<?>[1 + arguments.size()];
params[0] = owner.clazz;
for (int i = 0; i < arguments.size(); i++) {
params[i + 1] = PainlessLookup.defClassToObjectClass(arguments.get(i));
params[i + 1] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
}
returnValue = PainlessLookup.defClassToObjectClass(rtn);
returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn);
}
return MethodType.methodType(returnValue, params);
}

View File

@ -20,10 +20,10 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import java.util.Objects;
@ -157,7 +157,7 @@ public abstract class AExpression extends ANode {
return ecast;
} else {
if (PainlessLookup.isConstantType(expected)) {
if (PainlessLookupUtility.isAnyTypeConstant(expected)) {
// For the case where a cast is required, a constant is set,
// and the constant can be immediately cast to the expected type.
// An EConstant replaces this node with the constant cast appropriately

View File

@ -22,13 +22,13 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.Operation;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.def;
import java.util.ArrayList;
import java.util.List;

View File

@ -21,14 +21,14 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.Operation;
import org.elasticsearch.painless.WriterConstants;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import java.util.Objects;
import java.util.Set;
@ -106,7 +106,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply multiply [*] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -148,7 +149,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply divide [/] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -195,7 +197,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply remainder [%] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -242,7 +245,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply add [+] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -300,7 +304,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply subtract [-] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -358,7 +363,8 @@ public final class EBinary extends AExpression {
if (lhspromote == null || rhspromote == null) {
throw createError(new ClassCastException("Cannot apply left shift [<<] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote = lhspromote;
@ -405,7 +411,8 @@ public final class EBinary extends AExpression {
if (lhspromote == null || rhspromote == null) {
throw createError(new ClassCastException("Cannot apply right shift [>>] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote = lhspromote;
@ -455,7 +462,8 @@ public final class EBinary extends AExpression {
if (lhspromote == null || rhspromote == null) {
throw createError(new ClassCastException("Cannot apply unsigned shift [>>>] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (lhspromote == def.class || rhspromote == def.class) {
@ -498,7 +506,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply and [&] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -537,7 +546,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply xor [^] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;
@ -577,7 +587,8 @@ public final class EBinary extends AExpression {
if (promote == null) {
throw createError(new ClassCastException("Cannot apply or [|] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
actual = promote;

View File

@ -19,12 +19,12 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import java.util.List;
import java.util.Objects;

View File

@ -21,14 +21,14 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.FunctionRef;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@ -69,7 +69,7 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
defPointer = "D" + variable + "." + call + ",1";
} else {
// typed implementation
defPointer = "S" + PainlessLookup.ClassToName(captured.clazz) + "." + call + ",1";
defPointer = "S" + PainlessLookupUtility.anyTypeToPainlessTypeName(captured.clazz) + "." + call + ",1";
}
actual = String.class;
} else {
@ -77,7 +77,8 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
// static case
if (captured.clazz != def.class) {
try {
ref = new FunctionRef(locals.getPainlessLookup(), expected, PainlessLookup.ClassToName(captured.clazz), call, 1);
ref = new FunctionRef(
locals.getPainlessLookup(), expected, PainlessLookupUtility.anyTypeToPainlessTypeName(captured.clazz), call, 1);
// check casts between the interface method and the delegate method are legal
for (int i = 0; i < ref.interfaceMethod.arguments.size(); ++i) {
@ -109,7 +110,7 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
// typed interface, dynamic implementation
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
Type methodType = Type.getMethodType(MethodWriter.getType(expected), MethodWriter.getType(captured.clazz));
writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookup.ClassToName(expected));
writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.anyTypeToPainlessTypeName(expected));
} else {
// typed interface, typed implementation
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());

View File

@ -19,12 +19,12 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import java.util.Objects;
import java.util.Set;
@ -63,6 +63,6 @@ final class ECast extends AExpression {
@Override
public String toString() {
return singleLineToString(PainlessLookup.ClassToName(cast.to), child);
return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(cast.to), child);
}
}

View File

@ -21,13 +21,13 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.Operation;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
@ -93,7 +93,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply equals [==] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (promotedType == def.class) {
@ -142,7 +143,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply reference equals [===] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
left.expected = promotedType;
@ -182,7 +184,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply not equals [!=] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (promotedType == def.class) {
@ -231,7 +234,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply reference not equals [!==] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
left.expected = promotedType;
@ -271,7 +275,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply greater than or equals [>=] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (promotedType == def.class) {
@ -310,7 +315,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply greater than [>] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (promotedType == def.class) {
@ -349,7 +355,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply less than or equals [<=] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (promotedType == def.class) {
@ -388,7 +395,8 @@ public final class EComp extends AExpression {
if (promotedType == null) {
throw createError(new ClassCastException("Cannot apply less than [>=] to types " +
"[" + PainlessLookup.ClassToName(left.actual) + "] and [" + PainlessLookup.ClassToName(right.actual) + "]."));
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
}
if (promotedType == def.class) {

View File

@ -20,14 +20,14 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.FunctionRef;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.objectweb.asm.Type;
import java.util.Objects;
@ -69,12 +69,12 @@ public final class EFunctionRef extends AExpression implements ILambda {
PainlessMethod interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod;
if (interfaceMethod == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
"to [" + PainlessLookup.ClassToName(expected) + "], not a functional interface");
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface");
}
PainlessMethod delegateMethod = locals.getMethod(new PainlessMethodKey(call, interfaceMethod.arguments.size()));
if (delegateMethod == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
"to [" + PainlessLookup.ClassToName(expected) + "], function not found");
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], function not found");
}
ref = new FunctionRef(expected, interfaceMethod, delegateMethod, 0);

View File

@ -19,11 +19,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import java.util.Objects;
import java.util.Set;
@ -64,7 +64,8 @@ public final class EInstanceof extends AExpression {
}
// map to wrapped type for primitive types
resolvedType = clazz.isPrimitive() ? PainlessLookup.getBoxedType(clazz) : PainlessLookup.defClassToObjectClass(clazz);
resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.getBoxedAnyType(clazz) :
PainlessLookupUtility.painlessDefTypeToJavaObjectType(clazz);
// analyze and cast the expression
expression.analyze(locals);
@ -75,7 +76,7 @@ public final class EInstanceof extends AExpression {
primitiveExpression = expression.actual.isPrimitive();
// map to wrapped type for primitive types
expressionType = expression.actual.isPrimitive() ?
PainlessLookup.getBoxedType(expression.actual) : PainlessLookup.defClassToObjectClass(clazz);
PainlessLookupUtility.getBoxedAnyType(expression.actual) : PainlessLookupUtility.painlessDefTypeToJavaObjectType(clazz);
actual = boolean.class;
}

View File

@ -20,15 +20,15 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.FunctionRef;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.node.SFunction.FunctionReserved;
import org.objectweb.asm.Opcodes;
@ -122,13 +122,13 @@ public final class ELambda extends AExpression implements ILambda {
// we know the method statically, infer return type and any unknown/def types
interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod;
if (interfaceMethod == null) {
throw createError(new IllegalArgumentException("Cannot pass lambda to [" + PainlessLookup.ClassToName(expected) +
"], not a functional interface"));
throw createError(new IllegalArgumentException("Cannot pass lambda to " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface"));
}
// check arity before we manipulate parameters
if (interfaceMethod.arguments.size() != paramTypeStrs.size())
throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name +
"] in [" + PainlessLookup.ClassToName(expected) + "]");
"] in [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]");
// for method invocation, its allowed to ignore the return value
if (interfaceMethod.rtn == void.class) {
returnType = def.class;
@ -140,7 +140,7 @@ public final class ELambda extends AExpression implements ILambda {
for (int i = 0; i < paramTypeStrs.size(); i++) {
String paramType = paramTypeStrs.get(i);
if (paramType == null) {
actualParamTypeStrs.add(PainlessLookup.ClassToName(interfaceMethod.arguments.get(i)));
actualParamTypeStrs.add(PainlessLookupUtility.anyTypeToPainlessTypeName(interfaceMethod.arguments.get(i)));
} else {
actualParamTypeStrs.add(paramType);
}
@ -162,15 +162,15 @@ public final class ELambda extends AExpression implements ILambda {
List<String> paramTypes = new ArrayList<>(captures.size() + actualParamTypeStrs.size());
List<String> paramNames = new ArrayList<>(captures.size() + paramNameStrs.size());
for (Variable var : captures) {
paramTypes.add(PainlessLookup.ClassToName(var.clazz));
paramTypes.add(PainlessLookupUtility.anyTypeToPainlessTypeName(var.clazz));
paramNames.add(var.name);
}
paramTypes.addAll(actualParamTypeStrs);
paramNames.addAll(paramNameStrs);
// desugar lambda body into a synthetic method
desugared = new SFunction(reserved, location, PainlessLookup.ClassToName(returnType), name,
paramTypes, paramNames, statements, true);
desugared = new SFunction(reserved, location, PainlessLookupUtility.anyTypeToPainlessTypeName(returnType), name,
paramTypes, paramNames, statements, true);
desugared.generateSignature(locals.getPainlessLookup());
desugared.analyze(Locals.newLambdaScope(locals.getProgramScope(), returnType,
desugared.parameters, captures.size(), reserved.getMaxLoopCounter()));

View File

@ -19,13 +19,13 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import java.util.ArrayList;
import java.util.List;

View File

@ -19,13 +19,13 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import java.util.HashMap;
import java.util.List;

View File

@ -19,12 +19,12 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import java.util.List;

View File

@ -19,11 +19,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.objectweb.asm.Opcodes;
import java.util.Set;
@ -53,7 +53,7 @@ public final class ENull extends AExpression {
if (expected != null) {
if (expected.isPrimitive()) {
throw createError(new IllegalArgumentException(
"Cannot cast null to a primitive type [" + PainlessLookup.ClassToName(expected) + "]."));
"Cannot cast null to a primitive type [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]."));
}
actual = expected;

View File

@ -21,13 +21,13 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.Operation;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@ -93,7 +93,8 @@ public final class EUnary extends AExpression {
promote = AnalyzerCaster.promoteNumeric(child.actual, false);
if (promote == null) {
throw createError(new ClassCastException("Cannot apply not [~] to type [" + PainlessLookup.ClassToName(child.actual) + "]."));
throw createError(new ClassCastException("Cannot apply not [~] to type " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(child.actual) + "]."));
}
child.expected = promote;
@ -122,8 +123,8 @@ public final class EUnary extends AExpression {
promote = AnalyzerCaster.promoteNumeric(child.actual, true);
if (promote == null) {
throw createError(
new ClassCastException("Cannot apply positive [+] to type [" + PainlessLookup.ClassToName(child.actual) + "]."));
throw createError(new ClassCastException("Cannot apply positive [+] to type " +
"[" + PainlessLookupUtility.painlessDefTypeToJavaObjectType(child.actual) + "]."));
}
child.expected = promote;
@ -156,8 +157,8 @@ public final class EUnary extends AExpression {
promote = AnalyzerCaster.promoteNumeric(child.actual, true);
if (promote == null) {
throw createError(
new ClassCastException("Cannot apply negative [-] to type [" + PainlessLookup.ClassToName(child.actual) + "]."));
throw createError(new ClassCastException("Cannot apply negative [-] to type " +
"[" + PainlessLookupUtility.painlessDefTypeToJavaObjectType(child.actual) + "]."));
}
child.expected = promote;

View File

@ -19,12 +19,12 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import java.util.List;
import java.util.Map;
@ -67,8 +67,8 @@ public final class PBrace extends AStoreable {
} else if (List.class.isAssignableFrom(prefix.actual)) {
sub = new PSubListShortcut(location, locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual), index);
} else {
throw createError(
new IllegalArgumentException("Illegal array access on type [" + PainlessLookup.ClassToName(prefix.actual) + "]."));
throw createError(new IllegalArgumentException("Illegal array access on type " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual) + "]."));
}
sub.write = write;

View File

@ -19,15 +19,15 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import java.util.List;
import java.util.Objects;
@ -74,7 +74,7 @@ public final class PCallInvoke extends AExpression {
PainlessClass struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual);
if (prefix.actual.isPrimitive()) {
struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookup.getBoxedType(prefix.actual));
struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.getBoxedAnyType(prefix.actual));
}
PainlessMethodKey methodKey = new PainlessMethodKey(name, arguments.size());

View File

@ -19,16 +19,16 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessField;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessField;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import java.util.List;
import java.util.Map;
@ -64,7 +64,7 @@ public final class PField extends AStoreable {
prefix = prefix.cast(locals);
if (prefix.actual.isArray()) {
sub = new PSubArrayLength(location, PainlessLookup.ClassToName(prefix.actual), value);
sub = new PSubArrayLength(location, PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual), value);
} else if (prefix.actual == def.class) {
sub = new PSubDefField(location, value);
} else {
@ -86,7 +86,7 @@ public final class PField extends AStoreable {
new PainlessMethodKey("set" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 1));
if (getter != null || setter != null) {
sub = new PSubShortcut(location, value, PainlessLookup.ClassToName(prefix.actual), getter, setter);
sub = new PSubShortcut(location, value, PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual), getter, setter);
} else {
EConstant index = new EConstant(location, value);
index.analyze(locals);
@ -104,7 +104,7 @@ public final class PField extends AStoreable {
if (sub == null) {
throw createError(new IllegalArgumentException(
"Unknown field [" + value + "] for type [" + PainlessLookup.ClassToName(prefix.actual) + "]."));
"Unknown field [" + value + "] for type [" + PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual) + "]."));
}
if (nullSafe) {

View File

@ -19,11 +19,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessMethod;
import java.util.List;
import java.util.Objects;

View File

@ -20,11 +20,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.def;
import org.objectweb.asm.Type;
import java.util.Objects;

View File

@ -20,11 +20,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.def;
import org.objectweb.asm.Type;
import java.util.ArrayList;

View File

@ -20,11 +20,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.def;
import java.util.Objects;
import java.util.Set;

View File

@ -19,12 +19,12 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessField;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessField;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import java.lang.reflect.Modifier;
import java.util.Objects;
@ -51,8 +51,8 @@ final class PSubField extends AStoreable {
@Override
void analyze(Locals locals) {
if (write && Modifier.isFinal(field.modifiers)) {
throw createError(new IllegalArgumentException(
"Cannot write to read-only field [" + field.name + "] for type [" + PainlessLookup.ClassToName(field.clazz) + "]."));
throw createError(new IllegalArgumentException("Cannot write to read-only field [" + field.name + "] for type " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(field.clazz) + "]."));
}
actual = field.clazz;

View File

@ -19,13 +19,13 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.WriterConstants;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import java.util.Objects;

View File

@ -19,12 +19,12 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import java.util.Objects;

View File

@ -19,11 +19,11 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessMethod;
import java.util.Set;

View File

@ -19,13 +19,13 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.def;
import java.util.Objects;
import java.util.Set;
@ -84,8 +84,8 @@ public class SEach extends AStatement {
} else if (expression.actual == def.class || Iterable.class.isAssignableFrom(expression.actual)) {
sub = new SSubEachIterable(location, variable, expression, block);
} else {
throw createError(
new IllegalArgumentException("Illegal for each type [" + PainlessLookup.ClassToName(expression.actual) + "]."));
throw createError(new IllegalArgumentException("Illegal for each type " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expression.actual) + "]."));
}
sub.analyze(locals);

View File

@ -22,8 +22,6 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.CompilerSettings;
import org.elasticsearch.painless.Constant;
import org.elasticsearch.painless.Def;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Parameter;
@ -31,6 +29,9 @@ import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.WriterConstants;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.node.SSource.Reserved;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Handle;
@ -135,7 +136,7 @@ public final class SFunction extends AStatement {
try {
Class<?> paramType = painlessLookup.getJavaClassFromPainlessType(this.paramTypeStrs.get(param));
paramClasses[param] = PainlessLookup.defClassToObjectClass(paramType);
paramClasses[param] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(paramType);
paramTypes.add(paramType);
parameters.add(new Parameter(location, paramNameStrs.get(param), paramType));
} catch (IllegalArgumentException exception) {
@ -144,8 +145,8 @@ public final class SFunction extends AStatement {
}
}
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(
name, MethodType.methodType(PainlessLookup.defClassToObjectClass(rtnType), paramClasses).toMethodDescriptorString());
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType(
PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtnType), paramClasses).toMethodDescriptorString());
this.method = new PainlessMethod(name, null, null, rtnType, paramTypes, method, Modifier.STATIC | Modifier.PRIVATE, null);
}

View File

@ -20,13 +20,13 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
@ -109,6 +109,6 @@ final class SSubEachArray extends AStatement {
@Override
public String toString() {
return singleLineToString(PainlessLookup.ClassToName(variable.clazz), variable.name, expression, block);
return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(variable.clazz), variable.name, expression, block);
}
}

View File

@ -21,16 +21,16 @@ package org.elasticsearch.painless.node;
import org.elasticsearch.painless.AnalyzerCaster;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessCast;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.PainlessMethodKey;
import org.elasticsearch.painless.lookup.def;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
@ -81,8 +81,8 @@ final class SSubEachIterable extends AStatement {
getPainlessStructFromJavaClass(expression.actual).methods.get(new PainlessMethodKey("iterator", 0));
if (method == null) {
throw createError(new IllegalArgumentException(
"Unable to create iterator for the type [" + PainlessLookup.ClassToName(expression.actual) + "]."));
throw createError(new IllegalArgumentException("Unable to create iterator for the type " +
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expression.actual) + "]."));
}
}
@ -133,6 +133,6 @@ final class SSubEachIterable extends AStatement {
@Override
public String toString() {
return singleLineToString(PainlessLookup.ClassToName(variable.clazz), variable.name, expression, block);
return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(variable.clazz), variable.name, expression, block);
}
}

View File

@ -19,7 +19,8 @@
package org.elasticsearch.rest;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.settings.Setting;
@ -43,7 +44,7 @@ import static org.hamcrest.Matchers.hasToString;
public class Netty4BadRequestIT extends ESRestTestCase {
public void testBadRequest() throws IOException {
final Response response = client().performRequest("GET", "/_nodes/settings", Collections.emptyMap());
final Response response = client().performRequest(new Request("GET", "/_nodes/settings"));
final ObjectPath objectPath = ObjectPath.createFromResponse(response);
final Map<String, Object> map = objectPath.evaluate("nodes");
int maxMaxInitialLineLength = Integer.MIN_VALUE;
@ -77,9 +78,9 @@ public class Netty4BadRequestIT extends ESRestTestCase {
}
public void testInvalidParameterValue() throws IOException {
final ResponseException e = expectThrows(
ResponseException.class,
() -> client().performRequest("GET", "/_cluster/settings", Collections.singletonMap("pretty", "neither-true-nor-false")));
final Request request = new Request("GET", "/_cluster/settings");
request.addParameter("pretty", "neither-true-nor-false");
final ResponseException e = expectThrows(ResponseException.class, () -> client().performRequest(request));
final Response response = e.getResponse();
assertThat(response.getStatusLine().getStatusCode(), equalTo(400));
final ObjectPath objectPath = ObjectPath.createFromResponse(response);
@ -89,9 +90,11 @@ public class Netty4BadRequestIT extends ESRestTestCase {
}
public void testInvalidHeaderValue() throws IOException {
final BasicHeader header = new BasicHeader("Content-Type", "\t");
final ResponseException e =
expectThrows(ResponseException.class, () -> client().performRequest("GET", "/_cluster/settings", header));
final Request request = new Request("GET", "/_cluster/settings");
final RequestOptions.Builder options = request.getOptions().toBuilder();
options.addHeader("Content-Type", "\t");
request.setOptions(options);
final ResponseException e = expectThrows(ResponseException.class, () -> client().performRequest(request));
final Response response = e.getResponse();
assertThat(response.getStatusLine().getStatusCode(), equalTo(400));
final ObjectPath objectPath = ObjectPath.createFromResponse(response);

View File

@ -19,8 +19,7 @@
package org.elasticsearch.rest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -57,8 +56,9 @@ public class Netty4HeadBodyIsEmptyIT extends ESRestTestCase {
builder.field("test", "test");
}
builder.endObject();
client().performRequest("PUT", "/" + indexName + "/" + typeName + "/" + "1", emptyMap(),
new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON));
Request request = new Request("PUT", "/" + indexName + "/" + typeName + "/" + "1");
request.setJsonEntity(Strings.toString(builder));
client().performRequest(request);
}
}
@ -109,8 +109,9 @@ public class Netty4HeadBodyIsEmptyIT extends ESRestTestCase {
}
builder.endObject();
client().performRequest("POST", "_aliases", emptyMap(), new StringEntity(Strings.toString(builder),
ContentType.APPLICATION_JSON));
Request request = new Request("POST", "/_aliases");
request.setJsonEntity(Strings.toString(builder));
client().performRequest(request);
headTestCase("/_alias/test_alias", emptyMap(), greaterThan(0));
headTestCase("/test/_alias/test_alias", emptyMap(), greaterThan(0));
}
@ -135,8 +136,9 @@ public class Netty4HeadBodyIsEmptyIT extends ESRestTestCase {
}
builder.endObject();
client().performRequest("PUT", "/_template/template", emptyMap(),
new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON));
Request request = new Request("PUT", "/_template/template");
request.setJsonEntity(Strings.toString(builder));
client().performRequest(request);
headTestCase("/_template/template", emptyMap(), greaterThan(0));
}
}
@ -164,8 +166,10 @@ public class Netty4HeadBodyIsEmptyIT extends ESRestTestCase {
builder.endObject();
}
builder.endObject();
client().performRequest("PUT", "/test-no-source", emptyMap(), new StringEntity(Strings.toString(builder),
ContentType.APPLICATION_JSON));
Request request = new Request("PUT", "/test-no-source");
request.setJsonEntity(Strings.toString(builder));
client().performRequest(request);
createTestDoc("test-no-source", "test-no-source");
headTestCase("/test-no-source/test-no-source/1/_source", emptyMap(), NOT_FOUND.getStatus(), equalTo(0));
}
@ -190,7 +194,11 @@ public class Netty4HeadBodyIsEmptyIT extends ESRestTestCase {
final Map<String, String> params,
final int expectedStatusCode,
final Matcher<Integer> matcher) throws IOException {
Response response = client().performRequest("HEAD", url, params);
Request request = new Request("HEAD", url);
for (Map.Entry<String, String> param : params.entrySet()) {
request.addParameter(param.getKey(), param.getValue());
}
Response response = client().performRequest(request);
assertEquals(expectedStatusCode, response.getStatusLine().getStatusCode());
assertThat(Integer.valueOf(response.getHeader("Content-Length")), matcher);
assertNull("HEAD requests shouldn't have a response body but " + url + " did", response.getEntity());

View File

@ -21,16 +21,13 @@ package org.elasticsearch.repositories.hdfs;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ha.BadFencingConfigurationException;
@ -42,9 +39,7 @@ import org.apache.hadoop.ha.protocolPB.HAServiceProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdfs.tools.DFSHAAdmin;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.apache.http.nio.entity.NStringEntity;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.common.io.PathUtils;
@ -58,8 +53,6 @@ public class HaHdfsFailoverTestSuiteIT extends ESRestTestCase {
public void testHAFailoverWithRepository() throws Exception {
RestClient client = client();
Map<String, String> emptyParams = Collections.emptyMap();
Header contentHeader = new BasicHeader("Content-Type", "application/json");
String esKerberosPrincipal = System.getProperty("test.krb5.principal.es");
String hdfsKerberosPrincipal = System.getProperty("test.krb5.principal.hdfs");
@ -106,7 +99,8 @@ public class HaHdfsFailoverTestSuiteIT extends ESRestTestCase {
// Create repository
{
Response response = client.performRequest("PUT", "/_snapshot/hdfs_ha_repo_read", emptyParams, new NStringEntity(
Request request = new Request("PUT", "/_snapshot/hdfs_ha_repo_read");
request.setJsonEntity(
"{" +
"\"type\":\"hdfs\"," +
"\"settings\":{" +
@ -121,15 +115,15 @@ public class HaHdfsFailoverTestSuiteIT extends ESRestTestCase {
"\"conf.dfs.client.failover.proxy.provider.ha-hdfs\": " +
"\"org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider\"" +
"}" +
"}",
Charset.defaultCharset()), contentHeader);
"}");
Response response = client.performRequest(request);
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
}
// Get repository
{
Response response = client.performRequest("GET", "/_snapshot/hdfs_ha_repo_read/_all", emptyParams);
Response response = client.performRequest(new Request("GET", "/_snapshot/hdfs_ha_repo_read/_all"));
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
}
@ -138,7 +132,7 @@ public class HaHdfsFailoverTestSuiteIT extends ESRestTestCase {
// Get repository again
{
Response response = client.performRequest("GET", "/_snapshot/hdfs_ha_repo_read/_all", emptyParams);
Response response = client.performRequest(new Request("GET", "/_snapshot/hdfs_ha_repo_read/_all"));
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
}
}

View File

@ -20,6 +20,7 @@
package org.elasticsearch.qa.verify_version_constants;
import org.elasticsearch.Version;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.test.rest.yaml.ObjectPath;
@ -32,7 +33,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
public class VerifyVersionConstantsIT extends ESRestTestCase {
public void testLuceneVersionConstant() throws IOException, ParseException {
final Response response = client().performRequest("GET", "/");
final Response response = client().performRequest(new Request("GET", "/"));
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
final ObjectPath objectPath = ObjectPath.createFromResponse(response);
final String elasticsearchVersionString = objectPath.evaluate("version.number").toString();

View File

@ -47,7 +47,9 @@ setup:
- match: { _shards.total: 18 }
- is_true: _all
- is_true: indices.test1
- is_true: indices.test1.uuid
- is_true: indices.test2
- is_true: indices.test2.uuid
---

View File

@ -29,10 +29,13 @@ public class IndexStats implements Iterable<IndexShardStats> {
private final String index;
private final String uuid;
private final ShardStats shards[];
public IndexStats(String index, ShardStats[] shards) {
public IndexStats(String index, String uuid, ShardStats[] shards) {
this.index = index;
this.uuid = uuid;
this.shards = shards;
}
@ -40,6 +43,10 @@ public class IndexStats implements Iterable<IndexShardStats> {
return this.index;
}
public String getUuid() {
return uuid;
}
public ShardStats[] getShards() {
return this.shards;
}

View File

@ -26,6 +26,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.Index;
import java.io.IOException;
import java.util.ArrayList;
@ -84,19 +85,22 @@ public class IndicesStatsResponse extends BroadcastResponse {
}
Map<String, IndexStats> indicesStats = new HashMap<>();
Set<String> indices = new HashSet<>();
Set<Index> indices = new HashSet<>();
for (ShardStats shard : shards) {
indices.add(shard.getShardRouting().getIndexName());
indices.add(shard.getShardRouting().index());
}
for (String indexName : indices) {
for (Index index : indices) {
List<ShardStats> shards = new ArrayList<>();
String indexName = index.getName();
for (ShardStats shard : this.shards) {
if (shard.getShardRouting().getIndexName().equals(indexName)) {
shards.add(shard);
}
}
indicesStats.put(indexName, new IndexStats(indexName, shards.toArray(new ShardStats[shards.size()])));
indicesStats.put(
indexName, new IndexStats(indexName, index.getUUID(), shards.toArray(new ShardStats[shards.size()]))
);
}
this.indicesStats = indicesStats;
return indicesStats;
@ -169,7 +173,7 @@ public class IndicesStatsResponse extends BroadcastResponse {
builder.startObject(Fields.INDICES);
for (IndexStats indexStats : getIndices().values()) {
builder.startObject(indexStats.getIndex());
builder.field("uuid", indexStats.getUuid());
builder.startObject("primaries");
indexStats.getPrimaries().toXContent(builder, params);
builder.endObject();

View File

@ -76,6 +76,9 @@ public class UnifiedHighlighter implements Highlighter {
fieldValues = fieldValues.stream()
.map((s) -> convertFieldValue(fieldType, s))
.collect(Collectors.toList());
if (fieldValues.size() == 0) {
return null;
}
final IndexSearcher searcher = new IndexSearcher(hitContext.reader());
final CustomUnifiedHighlighter highlighter;
final String fieldValue = mergeFieldValues(fieldValues, MULTIVAL_SEP_CHAR);

View File

@ -153,6 +153,13 @@ public class IndicesStatsTests extends ESSingleNodeTestCase {
assertEquals(0, common.refresh.getListeners());
}
@SuppressWarnings("unchecked")
public void testUuidOnRootStatsIndices() {
String uuid = createIndex("test").indexUUID();
IndicesStatsResponse rsp = client().admin().indices().prepareStats().get();
assertEquals(uuid, rsp.getIndex("test").getUuid());
}
/**
* Gives access to package private IndicesStatsResponse constructor for test purpose.
**/
@ -160,5 +167,4 @@ public class IndicesStatsTests extends ESSingleNodeTestCase {
int failedShards, List<DefaultShardOperationFailedException> shardFailures) {
return new IndicesStatsResponse(shards, totalShards, successfulShards, failedShards, shardFailures);
}
}

View File

@ -0,0 +1,161 @@
[role="xpack"]
[[rollup-get-rollup-index-caps]]
=== Get Rollup Index Capabilities
++++
<titleabbrev>Get Rollup Index Caps</titleabbrev>
++++
experimental[]
This API returns the rollup capabilities of all jobs inside of a rollup index (e.g. the index where rollup data is stored).
A single rollup index may store the data for multiple rollup jobs, and may have a variety of capabilities depending on those jobs.
This API will allow you to determine:
1. What jobs are stored in an index (or indices specified via a pattern)?
2. What target indices were rolled up, what fields were used in those rollups and what aggregations can be performed on each job?
==== Request
`GET {index}/_xpack/rollup/data`
//===== Description
==== Path Parameters
`index`::
(string) Index or index-pattern of concrete rollup indices to check for capabilities.
==== Request Body
There is no request body for the Get Jobs API.
==== Authorization
You must have `monitor`, `monitor_rollup`, `manage` or `manage_rollup` cluster privileges to use this API.
For more information, see
{xpack-ref}/security-privileges.html[Security Privileges].
==== Examples
Imagine we have an index named `sensor-1` full of raw data. We know that the data will grow over time, so there
will be a `sensor-2`, `sensor-3`, etc. Let's create a Rollup job, which stores it's data in `sensor_rollup`:
[source,js]
--------------------------------------------------
PUT _xpack/rollup/job/sensor
{
"index_pattern": "sensor-*",
"rollup_index": "sensor_rollup",
"cron": "*/30 * * * * ?",
"page_size" :1000,
"groups" : {
"date_histogram": {
"field": "timestamp",
"interval": "1h",
"delay": "7d"
},
"terms": {
"fields": ["node"]
}
},
"metrics": [
{
"field": "temperature",
"metrics": ["min", "max", "sum"]
},
{
"field": "voltage",
"metrics": ["avg"]
}
]
}
--------------------------------------------------
// CONSOLE
// TEST[setup:sensor_index]
If at a later date, we'd like to determine what jobs and capabilities were stored in the `sensor_rollup` index, we can use the Get Rollup
Index API:
[source,js]
--------------------------------------------------
GET /sensor_rollup/_xpack/rollup/data
--------------------------------------------------
// CONSOLE
// TEST[continued]
Note how we are requesting the concrete rollup index name (`sensor_rollup`) as the first part of the URL.
This will yield the following response:
[source,js]
----
{
"sensor_rollup" : {
"rollup_jobs" : [
{
"job_id" : "sensor",
"rollup_index" : "sensor_rollup",
"index_pattern" : "sensor-*",
"fields" : {
"node" : [
{
"agg" : "terms"
}
],
"temperature" : [
{
"agg" : "min"
},
{
"agg" : "max"
},
{
"agg" : "sum"
}
],
"timestamp" : [
{
"agg" : "date_histogram",
"time_zone" : "UTC",
"interval" : "1h",
"delay": "7d"
}
],
"voltage" : [
{
"agg" : "avg"
}
]
}
}
]
}
}
----
// TESTRESPONSE
The response that is returned contains information that is similar to the original Rollup configuration, but formatted
differently. First, there are some house-keeping details: the Rollup job's ID, the index that holds the rolled data,
the index pattern that the job was targeting.
Next it shows a list of fields that contain data eligible for rollup searches. Here we see four fields: `node`, `temperature`,
`timestamp` and `voltage`. Each of these fields list the aggregations that are possible. For example, you can use a min, max
or sum aggregation on the `temperature` field, but only a `date_histogram` on `timestamp`.
Note that the `rollup_jobs` element is an array; there can be multiple, independent jobs configured for a single index
or index pattern. Each of these jobs may have different configurations, so the API returns a list of all the various
configurations available.
Like other APIs that interact with indices, you can specify index patterns instead of explicit indices:
[source,js]
--------------------------------------------------
GET /*_rollup/_xpack/rollup/data
--------------------------------------------------
// CONSOLE
// TEST[continued]

View File

@ -139,7 +139,7 @@ public class GetRollupCapsAction extends Action<GetRollupCapsAction.Response> {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
for (Map.Entry<String, RollableIndexCaps> entry : jobs.entrySet()) {
entry.getValue().toXContent(builder, params);
entry.getValue().toXContent(builder, params);
}
builder.endObject();
return builder;

View File

@ -0,0 +1,195 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.rollup.action;
import org.elasticsearch.action.Action;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
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.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.rollup.RollupField;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
public class GetRollupIndexCapsAction extends Action<GetRollupIndexCapsAction.Response> {
public static final GetRollupIndexCapsAction INSTANCE = new GetRollupIndexCapsAction();
public static final String NAME = "indices:data/read/xpack/rollup/get/index/caps";
public static final ParseField CONFIG = new ParseField("config");
public static final ParseField STATUS = new ParseField("status");
private static final ParseField INDICES_OPTIONS = new ParseField("indices_options");
private GetRollupIndexCapsAction() {
super(NAME);
}
@Override
public Response newResponse() {
return new Response();
}
public static class Request extends ActionRequest implements IndicesRequest.Replaceable, ToXContent {
private String[] indices;
private IndicesOptions options;
public Request(String[] indices) {
this(indices, IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED);
}
public Request(String[] indices, IndicesOptions options) {
this.indices = indices;
this.options = options;
}
public Request() {}
@Override
public IndicesOptions indicesOptions() {
return options;
}
@Override
public String[] indices() {
return indices;
}
@Override
public IndicesRequest indices(String... indices) {
Objects.requireNonNull(indices, "indices must not be null");
for (String index : indices) {
Objects.requireNonNull(index, "index must not be null");
}
this.indices = indices;
return this;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
this.indices = in.readStringArray();
this.options = IndicesOptions.readIndicesOptions(in);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeStringArray(indices);
options.writeIndicesOptions(out);
}
@Override
public ActionRequestValidationException validate() {
return null;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.array(RollupField.ID.getPreferredName(), indices);
builder.field(INDICES_OPTIONS.getPreferredName(), options);
return builder;
}
@Override
public int hashCode() {
return Objects.hash(Arrays.hashCode(indices), options);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Request other = (Request) obj;
return Arrays.equals(indices, other.indices)
&& Objects.equals(options, other.options);
}
}
public static class RequestBuilder extends ActionRequestBuilder<Request, Response> {
protected RequestBuilder(ElasticsearchClient client, GetRollupIndexCapsAction action) {
super(client, action, new Request());
}
}
public static class Response extends ActionResponse implements Writeable, ToXContentObject {
private Map<String, RollableIndexCaps> jobs = Collections.emptyMap();
public Response() {
}
public Response(Map<String, RollableIndexCaps> jobs) {
this.jobs = Objects.requireNonNull(jobs);
}
Response(StreamInput in) throws IOException {
jobs = in.readMap(StreamInput::readString, RollableIndexCaps::new);
}
public Map<String, RollableIndexCaps> getJobs() {
return jobs;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeMap(jobs, StreamOutput::writeString, (out1, value) -> value.writeTo(out1));
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
for (Map.Entry<String, RollableIndexCaps> entry : jobs.entrySet()) {
entry.getValue().toXContent(builder, params);
}
builder.endObject();
return builder;
}
@Override
public int hashCode() {
return Objects.hash(jobs);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Response other = (Response) obj;
return Objects.equals(jobs, other.jobs);
}
@Override
public final String toString() {
return Strings.toString(this);
}
}
}

View File

@ -45,7 +45,7 @@ public class IndicesStatsMonitoringDocTests extends BaseFilteredMonitoringDocTes
@Before
public void setUp() throws Exception {
super.setUp();
indicesStats = Collections.singletonList(new IndexStats("index-0", new ShardStats[] {
indicesStats = Collections.singletonList(new IndexStats("index-0", "dcvO5uZATE-EhIKc3tk9Bg", new ShardStats[] {
// Primaries
new ShardStats(mockShardRouting(true), mockShardPath(), mockCommonStats(), null, null),
new ShardStats(mockShardRouting(true), mockShardPath(), mockCommonStats(), null, null),

View File

@ -38,6 +38,7 @@ import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.rollup.RollupField;
import org.elasticsearch.xpack.core.rollup.action.DeleteRollupJobAction;
import org.elasticsearch.xpack.core.rollup.action.GetRollupCapsAction;
import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction;
import org.elasticsearch.xpack.core.rollup.action.GetRollupJobsAction;
import org.elasticsearch.xpack.core.rollup.action.PutRollupJobAction;
import org.elasticsearch.xpack.core.rollup.action.RollupSearchAction;
@ -47,6 +48,7 @@ import org.elasticsearch.xpack.core.scheduler.SchedulerEngine;
import org.elasticsearch.xpack.core.template.TemplateUtils;
import org.elasticsearch.xpack.rollup.action.TransportDeleteRollupJobAction;
import org.elasticsearch.xpack.rollup.action.TransportGetRollupCapsAction;
import org.elasticsearch.xpack.rollup.action.TransportGetRollupIndexCapsAction;
import org.elasticsearch.xpack.rollup.action.TransportGetRollupJobAction;
import org.elasticsearch.xpack.rollup.action.TransportPutRollupJobAction;
import org.elasticsearch.xpack.rollup.action.TransportRollupSearchAction;
@ -55,6 +57,7 @@ import org.elasticsearch.xpack.rollup.action.TransportStopRollupAction;
import org.elasticsearch.xpack.rollup.job.RollupJobTask;
import org.elasticsearch.xpack.rollup.rest.RestDeleteRollupJobAction;
import org.elasticsearch.xpack.rollup.rest.RestGetRollupCapsAction;
import org.elasticsearch.xpack.rollup.rest.RestGetRollupIndexCapsAction;
import org.elasticsearch.xpack.rollup.rest.RestGetRollupJobsAction;
import org.elasticsearch.xpack.rollup.rest.RestPutRollupJobAction;
import org.elasticsearch.xpack.rollup.rest.RestRollupSearchAction;
@ -136,13 +139,14 @@ public class Rollup extends Plugin implements ActionPlugin, PersistentTaskPlugin
}
return Arrays.asList(
new RestRollupSearchAction(settings, restController),
new RestPutRollupJobAction(settings, restController),
new RestStartRollupJobAction(settings, restController),
new RestStopRollupJobAction(settings, restController),
new RestDeleteRollupJobAction(settings, restController),
new RestGetRollupJobsAction(settings, restController),
new RestGetRollupCapsAction(settings, restController)
new RestRollupSearchAction(settings, restController),
new RestPutRollupJobAction(settings, restController),
new RestStartRollupJobAction(settings, restController),
new RestStopRollupJobAction(settings, restController),
new RestDeleteRollupJobAction(settings, restController),
new RestGetRollupJobsAction(settings, restController),
new RestGetRollupCapsAction(settings, restController),
new RestGetRollupIndexCapsAction(settings, restController)
);
}
@ -153,13 +157,14 @@ public class Rollup extends Plugin implements ActionPlugin, PersistentTaskPlugin
return emptyList();
}
return Arrays.asList(
new ActionHandler<>(RollupSearchAction.INSTANCE, TransportRollupSearchAction.class),
new ActionHandler<>(PutRollupJobAction.INSTANCE, TransportPutRollupJobAction.class),
new ActionHandler<>(StartRollupJobAction.INSTANCE, TransportStartRollupAction.class),
new ActionHandler<>(StopRollupJobAction.INSTANCE, TransportStopRollupAction.class),
new ActionHandler<>(DeleteRollupJobAction.INSTANCE, TransportDeleteRollupJobAction.class),
new ActionHandler<>(GetRollupJobsAction.INSTANCE, TransportGetRollupJobAction.class),
new ActionHandler<>(GetRollupCapsAction.INSTANCE, TransportGetRollupCapsAction.class)
new ActionHandler<>(RollupSearchAction.INSTANCE, TransportRollupSearchAction.class),
new ActionHandler<>(PutRollupJobAction.INSTANCE, TransportPutRollupJobAction.class),
new ActionHandler<>(StartRollupJobAction.INSTANCE, TransportStartRollupAction.class),
new ActionHandler<>(StopRollupJobAction.INSTANCE, TransportStopRollupAction.class),
new ActionHandler<>(DeleteRollupJobAction.INSTANCE, TransportDeleteRollupJobAction.class),
new ActionHandler<>(GetRollupJobsAction.INSTANCE, TransportGetRollupJobAction.class),
new ActionHandler<>(GetRollupCapsAction.INSTANCE, TransportGetRollupCapsAction.class),
new ActionHandler<>(GetRollupIndexCapsAction.INSTANCE, TransportGetRollupIndexCapsAction.class)
);
}

View File

@ -44,7 +44,6 @@ public class TransportGetRollupCapsAction extends HandledTransportAction<GetRoll
@Override
protected void doExecute(Task task, GetRollupCapsAction.Request request, ActionListener<GetRollupCapsAction.Response> listener) {
Map<String, RollableIndexCaps> allCaps = getCaps(request.getIndexPattern(), clusterService.state().getMetaData().indices());
listener.onResponse(new GetRollupCapsAction.Response(allCaps));
}
@ -67,7 +66,7 @@ public class TransportGetRollupCapsAction extends HandledTransportAction<GetRoll
jobCaps.forEach(jobCap -> {
String pattern = indexPattern.equals(MetaData.ALL)
? jobCap.getIndexPattern() : indexPattern;
? jobCap.getIndexPattern() : indexPattern;
// Do we already have an entry for this index pattern?
RollableIndexCaps indexCaps = allCaps.get(pattern);
@ -98,11 +97,11 @@ public class TransportGetRollupCapsAction extends HandledTransportAction<GetRoll
}
RollupIndexCaps caps = RollupIndexCaps.parseMetadataXContent(
new BytesArray(rollupMapping.source().uncompressed()), indexName);
new BytesArray(rollupMapping.source().uncompressed()), indexName);
if (caps.hasCaps()) {
return Optional.of(caps);
}
return Optional.empty();
}
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.rollup.action;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction;
import org.elasticsearch.xpack.core.rollup.action.RollableIndexCaps;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Supplier;
import java.util.stream.StreamSupport;
public class TransportGetRollupIndexCapsAction extends HandledTransportAction<GetRollupIndexCapsAction.Request,
GetRollupIndexCapsAction.Response> {
private final ClusterService clusterService;
@Inject
public TransportGetRollupIndexCapsAction(Settings settings, TransportService transportService,
ClusterService clusterService, ActionFilters actionFilters) {
super(settings, GetRollupIndexCapsAction.NAME, transportService, actionFilters,
(Supplier<GetRollupIndexCapsAction.Request>) GetRollupIndexCapsAction.Request::new);
this.clusterService = clusterService;
}
@Override
protected void doExecute(Task task, GetRollupIndexCapsAction.Request request,
ActionListener<GetRollupIndexCapsAction.Response> listener) {
IndexNameExpressionResolver resolver = new IndexNameExpressionResolver(clusterService.getSettings());
String[] indices = resolver.concreteIndexNames(clusterService.state(),
request.indicesOptions(), request.indices());
Map<String, RollableIndexCaps> allCaps = getCapsByRollupIndex(Arrays.asList(indices),
clusterService.state().getMetaData().indices());
listener.onResponse(new GetRollupIndexCapsAction.Response(allCaps));
}
static Map<String, RollableIndexCaps> getCapsByRollupIndex(List<String> resolvedIndexNames,
ImmutableOpenMap<String, IndexMetaData> indices) {
Map<String, RollableIndexCaps> allCaps = new TreeMap<>();
StreamSupport.stream(indices.spliterator(), false)
.filter(entry -> resolvedIndexNames.contains(entry.key))
.forEach(entry -> {
// Does this index have rollup metadata?
TransportGetRollupCapsAction.findRollupIndexCaps(entry.key, entry.value)
.ifPresent(cap -> {
cap.getJobCaps().forEach(jobCap -> {
// Do we already have an entry for this index?
RollableIndexCaps indexCaps = allCaps.get(jobCap.getRollupIndex());
if (indexCaps == null) {
indexCaps = new RollableIndexCaps(jobCap.getRollupIndex());
}
indexCaps.addJobCap(jobCap);
allCaps.put(jobCap.getRollupIndex(), indexCaps);
});
});
});
return allCaps;
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.rollup.rest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestToXContentListener;
import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction;
public class RestGetRollupIndexCapsAction extends BaseRestHandler {
public static final ParseField INDEX = new ParseField("index");
public RestGetRollupIndexCapsAction(Settings settings, RestController controller) {
super(settings);
controller.registerHandler(RestRequest.Method.GET, "/{index}/_xpack/rollup/data", this);
}
@Override
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) {
String index = restRequest.param(INDEX.getPreferredName());
IndicesOptions options = IndicesOptions.fromRequest(restRequest, IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED);
GetRollupIndexCapsAction.Request request = new GetRollupIndexCapsAction.Request(new String[]{index}, options);
return channel -> client.execute(GetRollupIndexCapsAction.INSTANCE, request, new RestToXContentListener<>(channel));
}
@Override
public String getName() {
return "rollup_get_caps_action";
}
}

View File

@ -11,11 +11,11 @@ import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.test.AbstractStreamableTestCase;
import org.elasticsearch.xpack.core.rollup.ConfigTestHelpers;
import org.elasticsearch.xpack.core.rollup.RollupField;
import org.elasticsearch.xpack.core.rollup.action.GetRollupCapsAction;
import org.elasticsearch.xpack.core.rollup.action.RollableIndexCaps;
import org.elasticsearch.xpack.core.rollup.job.RollupJobConfig;
import org.elasticsearch.xpack.core.rollup.ConfigTestHelpers;
import org.mockito.Mockito;
import java.io.IOException;

View File

@ -0,0 +1,177 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.rollup.action;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.test.AbstractStreamableTestCase;
import org.elasticsearch.xpack.core.rollup.ConfigTestHelpers;
import org.elasticsearch.xpack.core.rollup.RollupField;
import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction;
import org.elasticsearch.xpack.core.rollup.action.RollableIndexCaps;
import org.mockito.Mockito;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.xpack.rollup.action.TransportGetRollupIndexCapsAction.getCapsByRollupIndex;
import static org.hamcrest.Matchers.equalTo;
public class GetRollupIndexCapsActionRequestTests extends AbstractStreamableTestCase<GetRollupIndexCapsAction.Request> {
@Override
protected GetRollupIndexCapsAction.Request createTestInstance() {
if (randomBoolean()) {
return new GetRollupIndexCapsAction.Request(new String[]{MetaData.ALL});
}
return new GetRollupIndexCapsAction.Request(new String[]{randomAlphaOfLengthBetween(1, 20)});
}
@Override
protected GetRollupIndexCapsAction.Request createBlankInstance() {
return new GetRollupIndexCapsAction.Request();
}
public void testNoIndicesByRollup() {
ImmutableOpenMap<String, IndexMetaData> indices = new ImmutableOpenMap.Builder<String, IndexMetaData>().build();
Map<String, RollableIndexCaps> caps = getCapsByRollupIndex(Collections.singletonList("foo"), indices);
assertThat(caps.size(), equalTo(0));
}
public void testAllIndicesByRollupSingleRollup() throws IOException {
int num = randomIntBetween(1,5);
ImmutableOpenMap.Builder<String, IndexMetaData> indices = new ImmutableOpenMap.Builder<>(5);
int indexCounter = 0;
for (int j = 0; j < 5; j++) {
Map<String, Object> jobs = new HashMap<>(num);
for (int i = 0; i < num; i++) {
String jobName = randomAlphaOfLength(10);
String indexName = Integer.toString(indexCounter);
indexCounter += 1;
jobs.put(jobName, ConfigTestHelpers.getRollupJob(jobName).setRollupIndex("foo").build());
}
MappingMetaData mappingMeta = new MappingMetaData(RollupField.TYPE_NAME,
Collections.singletonMap(RollupField.TYPE_NAME,
Collections.singletonMap("_meta",
Collections.singletonMap(RollupField.ROLLUP_META, jobs))));
ImmutableOpenMap.Builder<String, MappingMetaData> mappings = ImmutableOpenMap.builder(1);
mappings.put(RollupField.TYPE_NAME, mappingMeta);
IndexMetaData meta = Mockito.mock(IndexMetaData.class);
Mockito.when(meta.getMappings()).thenReturn(mappings.build());
indices.put("foo", meta);
}
Map<String, RollableIndexCaps> caps = getCapsByRollupIndex(Collections.singletonList("foo"),
indices.build());
assertThat(caps.size(), equalTo(1));
}
public void testAllIndicesByRollupManyRollup() throws IOException {
ImmutableOpenMap.Builder<String, IndexMetaData> indices = new ImmutableOpenMap.Builder<>(5);
int indexCounter = 0;
for (int j = 0; j < 5; j++) {
Map<String, Object> jobs = new HashMap<>(1);
String jobName = randomAlphaOfLength(10);
String indexName = Integer.toString(indexCounter);
indexCounter += 1;
jobs.put(jobName, ConfigTestHelpers.getRollupJob(jobName)
.setIndexPattern(indexName)
.setRollupIndex("rollup_" + indexName).build());
MappingMetaData mappingMeta = new MappingMetaData(RollupField.TYPE_NAME,
Collections.singletonMap(RollupField.TYPE_NAME,
Collections.singletonMap("_meta",
Collections.singletonMap(RollupField.ROLLUP_META, jobs))));
ImmutableOpenMap.Builder<String, MappingMetaData> mappings = ImmutableOpenMap.builder(1);
mappings.put(RollupField.TYPE_NAME, mappingMeta);
IndexMetaData meta = Mockito.mock(IndexMetaData.class);
Mockito.when(meta.getMappings()).thenReturn(mappings.build());
indices.put("rollup_" + indexName, meta);
}
Map<String, RollableIndexCaps> caps = getCapsByRollupIndex(Arrays.asList(indices.keys().toArray(String.class)), indices.build());
assertThat(caps.size(), equalTo(5));
}
public void testOneIndexByRollupManyRollup() throws IOException {
ImmutableOpenMap.Builder<String, IndexMetaData> indices = new ImmutableOpenMap.Builder<>(5);
int indexCounter = 0;
for (int j = 0; j < 5; j++) {
Map<String, Object> jobs = new HashMap<>(1);
String jobName = randomAlphaOfLength(10);
String indexName = Integer.toString(indexCounter);
indexCounter += 1;
jobs.put(jobName, ConfigTestHelpers.getRollupJob(jobName)
.setIndexPattern("foo_" + indexName)
.setRollupIndex("rollup_" + indexName).build());
MappingMetaData mappingMeta = new MappingMetaData(RollupField.TYPE_NAME,
Collections.singletonMap(RollupField.TYPE_NAME,
Collections.singletonMap("_meta",
Collections.singletonMap(RollupField.ROLLUP_META, jobs))));
ImmutableOpenMap.Builder<String, MappingMetaData> mappings = ImmutableOpenMap.builder(1);
mappings.put(RollupField.TYPE_NAME, mappingMeta);
IndexMetaData meta = Mockito.mock(IndexMetaData.class);
Mockito.when(meta.getMappings()).thenReturn(mappings.build());
indices.put("rollup_" + indexName, meta);
}
Map<String, RollableIndexCaps> caps = getCapsByRollupIndex(Collections.singletonList("rollup_1"), indices.build());
assertThat(caps.size(), equalTo(1));
assertThat(caps.get("rollup_1").getIndexName(), equalTo("rollup_1"));
assertThat(caps.get("rollup_1").getJobCaps().size(), equalTo(1));
}
public void testOneIndexByRollupOneRollup() throws IOException {
ImmutableOpenMap.Builder<String, IndexMetaData> indices = new ImmutableOpenMap.Builder<>(5);
int indexCounter = 0;
for (int j = 0; j < 5; j++) {
Map<String, Object> jobs = new HashMap<>(1);
String jobName = randomAlphaOfLength(10);
String indexName = Integer.toString(indexCounter);
indexCounter += 1;
jobs.put(jobName, ConfigTestHelpers.getRollupJob(jobName)
.setIndexPattern("foo_" + indexName)
.setRollupIndex("rollup_foo").build());
MappingMetaData mappingMeta = new MappingMetaData(RollupField.TYPE_NAME,
Collections.singletonMap(RollupField.TYPE_NAME,
Collections.singletonMap("_meta",
Collections.singletonMap(RollupField.ROLLUP_META, jobs))));
ImmutableOpenMap.Builder<String, MappingMetaData> mappings = ImmutableOpenMap.builder(1);
mappings.put(RollupField.TYPE_NAME, mappingMeta);
IndexMetaData meta = Mockito.mock(IndexMetaData.class);
Mockito.when(meta.getMappings()).thenReturn(mappings.build());
indices.put("rollup_foo", meta);
}
Map<String, RollableIndexCaps> caps = getCapsByRollupIndex(Collections.singletonList("rollup_foo"), indices.build());
assertThat(caps.size(), equalTo(1));
assertThat(caps.get("rollup_foo").getIndexName(), equalTo("rollup_foo"));
assertThat(caps.get("rollup_foo").getJobCaps().size(), equalTo(1));
}
}

View File

@ -243,7 +243,12 @@ functionExpression
;
functionTemplate
: identifier '(' (setQuantifier? expression (',' expression)*)? ')'
: functionName '(' (setQuantifier? expression (',' expression)*)? ')'
;
functionName
: LEFT
| RIGHT
| identifier
;
constant

View File

@ -396,8 +396,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
@Override
public Function visitFunctionExpression(FunctionExpressionContext ctx) {
FunctionTemplateContext template = ctx.functionTemplate();
String name = visitIdentifier(template.identifier());
String name = template.functionName().getText();
boolean isDistinct = template.setQuantifier() != null && template.setQuantifier().DISTINCT() != null;
UnresolvedFunction.ResolutionType resolutionType =
isDistinct ? UnresolvedFunction.ResolutionType.DISTINCT : UnresolvedFunction.ResolutionType.STANDARD;

View File

@ -803,6 +803,18 @@ class SqlBaseBaseListener implements SqlBaseListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFunctionTemplate(SqlBaseParser.FunctionTemplateContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFunctionName(SqlBaseParser.FunctionNameContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFunctionName(SqlBaseParser.FunctionNameContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -473,6 +473,13 @@ class SqlBaseBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements SqlBa
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionTemplate(SqlBaseParser.FunctionTemplateContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionName(SqlBaseParser.FunctionNameContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -745,6 +745,16 @@ interface SqlBaseListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitFunctionTemplate(SqlBaseParser.FunctionTemplateContext ctx);
/**
* Enter a parse tree produced by {@link SqlBaseParser#functionName}.
* @param ctx the parse tree
*/
void enterFunctionName(SqlBaseParser.FunctionNameContext ctx);
/**
* Exit a parse tree produced by {@link SqlBaseParser#functionName}.
* @param ctx the parse tree
*/
void exitFunctionName(SqlBaseParser.FunctionNameContext ctx);
/**
* Enter a parse tree produced by the {@code nullLiteral}
* labeled alternative in {@link SqlBaseParser#constant}.

View File

@ -445,6 +445,12 @@ interface SqlBaseVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitFunctionTemplate(SqlBaseParser.FunctionTemplateContext ctx);
/**
* Visit a parse tree produced by {@link SqlBaseParser#functionName}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunctionName(SqlBaseParser.FunctionNameContext ctx);
/**
* Visit a parse tree produced by the {@code nullLiteral}
* labeled alternative in {@link SqlBaseParser#constant}.

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.sql.parser;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.expression.function.UnresolvedFunction;
import org.elasticsearch.xpack.sql.expression.function.scalar.arithmetic.Neg;
import org.elasticsearch.xpack.sql.type.DataType;
@ -15,6 +16,13 @@ public class ExpressionTests extends ESTestCase {
private final SqlParser parser = new SqlParser();
public void testTokenFunctionName() throws Exception {
Expression lt = parser.createExpression("LEFT()");
assertEquals(UnresolvedFunction.class, lt.getClass());
UnresolvedFunction uf = (UnresolvedFunction) lt;
assertEquals("LEFT", uf.functionName());
}
public void testLiteralLong() throws Exception {
Expression lt = parser.createExpression(String.valueOf(Long.MAX_VALUE));
assertEquals(Literal.class, lt.getClass());

View File

@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
public class SqlParserTests extends ESTestCase {
public void testSelectStar() {
singleProjection(project(parseStatement("SELECT * FROM foo")), UnresolvedStar.class);
}
@ -44,6 +45,11 @@ public class SqlParserTests extends ESTestCase {
assertEquals("SCORE", f.functionName());
}
public void testSelectRightFunction() {
UnresolvedFunction f = singleProjection(project(parseStatement("SELECT RIGHT()")), UnresolvedFunction.class);
assertEquals("RIGHT", f.functionName());
}
public void testOrderByField() {
Order.OrderDirection dir = randomFrom(Order.OrderDirection.values());
OrderBy ob = orderBy(parseStatement("SELECT * FROM foo ORDER BY bar" + stringForDirection(dir)));

View File

@ -0,0 +1,17 @@
{
"xpack.rollup.get_rollup_index_caps": {
"documentation": "",
"methods": [ "GET" ],
"url": {
"path": "/{index}/_xpack/rollup/data",
"paths": [ "/{index}/_xpack/rollup/data" ],
"parts": {
"index": {
"type": "string",
"required": true,
"description": "The rollup index or index pattern to obtain rollup capabilities from."
}
}
}
}
}

View File

@ -22,6 +22,18 @@ setup:
type: date
value_field:
type: integer
- do:
indices.create:
index: foo3
include_type_name: false
body:
mappings:
properties:
the_field:
type: date
value_field:
type: integer
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
@ -228,4 +240,3 @@ setup:
- agg: "min"
- agg: "max"
- agg: "sum"

View File

@ -0,0 +1,363 @@
setup:
- do:
indices.create:
index: foo
include_type_name: false
body:
mappings:
properties:
the_field:
type: date
value_field:
type: integer
- do:
indices.create:
index: foo2
include_type_name: false
body:
mappings:
properties:
the_field:
type: date
value_field:
type: integer
- do:
indices.create:
index: foo3
include_type_name: false
body:
mappings:
properties:
the_field:
type: date
value_field:
type: integer
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo
body: >
{
"index_pattern": "foo",
"rollup_index": "foo_rollup",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
---
"Verify one job caps by rollup index":
- do:
xpack.rollup.get_rollup_index_caps:
index: "foo_rollup"
- match:
foo_rollup:
rollup_jobs:
- job_id: "foo"
rollup_index: "foo_rollup"
index_pattern: "foo"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
---
"Verify two job caps by rollup index":
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo2
body: >
{
"index_pattern": "foo",
"rollup_index": "foo_rollup",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
- do:
xpack.rollup.get_rollup_index_caps:
index: "foo_rollup"
- match:
foo_rollup:
rollup_jobs:
- job_id: "foo"
rollup_index: "foo_rollup"
index_pattern: "foo"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
- job_id: "foo2"
rollup_index: "foo_rollup"
index_pattern: "foo"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
---
"Verify two different job caps by rollup index":
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo2
body: >
{
"index_pattern": "foo2",
"rollup_index": "foo_rollup2",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
- do:
xpack.rollup.get_rollup_index_caps:
index: "foo_rollup"
- match:
foo_rollup:
rollup_jobs:
- job_id: "foo"
rollup_index: "foo_rollup"
index_pattern: "foo"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
---
"Verify all job caps by rollup index":
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo2
body: >
{
"index_pattern": "foo2",
"rollup_index": "foo_rollup",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo3
body: >
{
"index_pattern": "foo3",
"rollup_index": "foo_rollup2",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
- do:
xpack.rollup.get_rollup_index_caps:
index: "_all"
- match:
$body:
foo_rollup:
rollup_jobs:
- job_id: "foo"
rollup_index: "foo_rollup"
index_pattern: "foo"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
- job_id: "foo2"
rollup_index: "foo_rollup"
index_pattern: "foo2"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
foo_rollup2:
rollup_jobs:
- job_id: "foo3"
rollup_index: "foo_rollup2"
index_pattern: "foo3"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"
---
"Verify index pattern":
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo2
body: >
{
"index_pattern": "foo2",
"rollup_index": "foo_rollup",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
xpack.rollup.put_job:
id: foo3
body: >
{
"index_pattern": "foo3",
"rollup_index": "foo_rollup2",
"cron": "*/30 * * * * ?",
"page_size" :10,
"groups" : {
"date_histogram": {
"field": "the_field",
"interval": "1h"
}
},
"metrics": [
{
"field": "value_field",
"metrics": ["min", "max", "sum"]
}
]
}
- do:
xpack.rollup.get_rollup_index_caps:
index: "*_rollup2"
- match:
$body:
foo_rollup2:
rollup_jobs:
- job_id: "foo3"
rollup_index: "foo_rollup2"
index_pattern: "foo3"
fields:
the_field:
- agg: "date_histogram"
interval: "1h"
time_zone: "UTC"
value_field:
- agg: "min"
- agg: "max"
- agg: "sum"