Skip to content

Commit 854d292

Browse files
committed
Support types table in lookup join docs
1 parent 2404dac commit 854d292

File tree

6 files changed

+186
-3
lines changed

6 files changed

+186
-3
lines changed

docs/reference/query-languages/esql/_snippets/commands/layout/lookup-join.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,6 @@ before the lookup when possible.
8181

8282
:::{include} ../examples/lookup-join.csv-spec/filterOnRightSide.md
8383
:::
84+
85+
:::{include} ../types/lookup-join.md
86+
:::
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
2+
3+
**Supported types**
4+
5+
| main | join | result |
6+
| --- | --- | --- |
7+
| boolean | boolean | boolean |
8+
| byte | byte | byte |
9+
| byte | double | double |
10+
| byte | float | float |
11+
| byte | half_float | half_float |
12+
| byte | integer | integer |
13+
| byte | long | long |
14+
| byte | scaled_float | scaled_float |
15+
| byte | short | short |
16+
| date | date | date |
17+
| date_nanos | date_nanos | date_nanos |
18+
| double | byte | double |
19+
| double | double | double |
20+
| double | float | double |
21+
| double | half_float | double |
22+
| double | integer | double |
23+
| double | long | double |
24+
| double | scaled_float | scaled_float |
25+
| double | short | double |
26+
| float | byte | float |
27+
| float | double | double |
28+
| float | float | float |
29+
| float | half_float | half_float |
30+
| float | integer | float |
31+
| float | long | float |
32+
| float | scaled_float | scaled_float |
33+
| float | short | float |
34+
| half_float | byte | half_float |
35+
| half_float | double | double |
36+
| half_float | float | float |
37+
| half_float | half_float | half_float |
38+
| half_float | integer | half_float |
39+
| half_float | long | half_float |
40+
| half_float | scaled_float | scaled_float |
41+
| half_float | short | half_float |
42+
| integer | byte | integer |
43+
| integer | double | double |
44+
| integer | float | float |
45+
| integer | half_float | half_float |
46+
| integer | integer | integer |
47+
| integer | long | long |
48+
| integer | scaled_float | scaled_float |
49+
| integer | short | integer |
50+
| ip | ip | ip |
51+
| keyword | keyword | keyword |
52+
| long | byte | long |
53+
| long | double | double |
54+
| long | float | float |
55+
| long | half_float | half_float |
56+
| long | integer | long |
57+
| long | long | long |
58+
| long | scaled_float | scaled_float |
59+
| long | short | long |
60+
| scaled_float | byte | scaled_float |
61+
| scaled_float | double | double |
62+
| scaled_float | float | scaled_float |
63+
| scaled_float | half_float | scaled_float |
64+
| scaled_float | integer | scaled_float |
65+
| scaled_float | long | scaled_float |
66+
| scaled_float | scaled_float | scaled_float |
67+
| scaled_float | short | scaled_float |
68+
| short | byte | short |
69+
| short | double | double |
70+
| short | float | float |
71+
| short | half_float | half_float |
72+
| short | integer | integer |
73+
| short | long | long |
74+
| short | scaled_float | scaled_float |
75+
| short | short | short |
76+
| text | keyword | keyword |
77+

docs/reference/query-languages/esql/esql-lookup-join.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,16 @@ To use `LOOKUP JOIN`, the following requirements must be met:
153153
* For text fields: You can only use text fields as the join key on the left-hand side of the join and only if they have a `.keyword` subfield
154154

155155
To obtain a join key with a compatible type, use a [conversion function](/reference/query-languages/esql/functions-operators/type-conversion-functions.md) if needed.
156+
* Both `KEYWORD` and `TEXT` are supported in the main index, but can only join against `KEYWORD` in the join index.
157+
* All numerical types are supported as join keys, using the same rules as applicable to the `==` operator when performing the join. FOr example, a `double` can be joined with an `integer`.
158+
* `DATE` and `DATE_NONES` can only be joined against the exact same type.
159+
* `IP` is supported, but `VERSION` is not.
156160

157-
For a complete list of supported data types and their internal representations, see the [Supported Field Types documentation](/reference/query-languages/esql/limitations.md#_supported_types).
161+
The list of unsupported fields includes all types not supported by {{esql}} as described in the [Unsupported Field Types documentation](/reference/query-languages/esql/limitations.md#_unsupported_types).
162+
as well as the following: `VERSION`, `UNSIGNED_LONG`, all spatial types like `GEO_POINT`, `GEO_SHAPE`, and all
163+
temporal periods like `DURATION` and `PERIOD`.
164+
165+
For a complete list of all types supported in `LOOKUP JOIN`, refer to the [`LOOKUP JOIN` supported types table](/reference/query-languages/esql/commands/processing-commands#esql-lookup-join).
158166

159167
## Usage notes
160168

x-pack/plugin/esql/build.gradle

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,45 @@ tasks.named("test").configure {
226226
}
227227
}
228228

229+
tasks.named("internalClusterTest").configure {
230+
if (buildParams.ci == false) {
231+
systemProperty 'generateDocs', true
232+
def injected = project.objects.newInstance(Injected)
233+
// Define the folder to delete and recreate
234+
def tempDir = file("build/testrun/internalClusterTest/temp/esql")
235+
doFirst {
236+
injected.fs.delete {
237+
it.delete(tempDir)
238+
}
239+
// Re-create this folder so we can save a table of generated examples to extract from csv-spec tests
240+
tempDir.mkdirs() // Recreate the folder
241+
}
242+
File snippetsFolder = file("build/testrun/internalClusterTest/temp/esql/_snippets")
243+
def snippetsDocFolder = file("${rootDir}/docs/reference/query-languages/esql/_snippets")
244+
def snippetsTree = fileTree(snippetsFolder).matching {
245+
include "**/types/*.md" // Recursively include all types/*.md files (effectively counting functions and operators)
246+
}
247+
248+
doLast {
249+
def snippets = snippetsTree.files.collect { it.name }
250+
int countSnippets = snippets.size()
251+
if (countSnippets == 0) {
252+
logger.quiet("ESQL Docs: No function/operator snippets created. Skipping sync.")
253+
} else {
254+
logger.quiet("ESQL Docs: Found $countSnippets generated function/operator snippets to patch into docs")
255+
injected.fs.sync {
256+
from snippetsFolder
257+
into snippetsDocFolder
258+
include '**/*.md'
259+
preserve {
260+
include '**/*.md'
261+
}
262+
}
263+
}
264+
}
265+
}
266+
}
267+
229268
/****************************************************************
230269
* Enable QA/rest integration tests for snapshot builds only *
231270
* TODO: Enable for all builds upon this feature release *

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/LookupJoinTypesIT.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
import org.elasticsearch.xpack.core.esql.action.ColumnInfo;
2020
import org.elasticsearch.xpack.esql.VerificationException;
2121
import org.elasticsearch.xpack.esql.core.type.DataType;
22+
import org.elasticsearch.xpack.esql.expression.function.DocsV3Support;
23+
import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry;
2224
import org.elasticsearch.xpack.esql.plan.logical.join.Join;
2325
import org.elasticsearch.xpack.esql.plugin.EsqlPlugin;
26+
import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter;
2427
import org.elasticsearch.xpack.spatial.SpatialPlugin;
2528
import org.elasticsearch.xpack.unsignedlong.UnsignedLongMapperPlugin;
2629
import org.elasticsearch.xpack.versionfield.VersionFieldPlugin;
@@ -36,6 +39,7 @@
3639
import java.util.Map;
3740
import java.util.Set;
3841
import java.util.function.Consumer;
42+
import java.util.function.Supplier;
3943
import java.util.stream.Collectors;
4044

4145
import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE;
@@ -265,6 +269,22 @@ private static boolean existingIndex(Collection<TestConfigs> existing, DataType
265269
return existing.stream().anyMatch(c -> c.exists(indexName));
266270
}
267271

272+
public void testOutputSupportedTypes() throws Exception {
273+
Map<List<DataType>, DataType> signatures = new LinkedHashMap<>();
274+
for (TestConfigs configs : testConfigurations.values()) {
275+
if (configs.group.equals("unsupported") || configs.group.equals("union-types")) {
276+
continue;
277+
}
278+
for (TestConfig config : configs.configs.values()) {
279+
if (config instanceof TestConfigPasses) {
280+
DataType commonType = EsqlDataTypeConverter.commonType(config.mainType(), config.lookupType());
281+
signatures.put(List.of(config.mainType(), config.lookupType()), commonType);
282+
}
283+
}
284+
}
285+
saveJoinTypes(() -> signatures);
286+
}
287+
268288
public void testLookupJoinStrings() {
269289
testLookupJoinTypes("strings");
270290
}
@@ -747,4 +767,18 @@ public void doTest() {
747767
private boolean isValidDataType(DataType dataType) {
748768
return UNDER_CONSTRUCTION.get(dataType) == null || UNDER_CONSTRUCTION.get(dataType).isEnabled();
749769
}
770+
771+
private static void saveJoinTypes(Supplier<Map<List<DataType>, DataType>> signatures) throws Exception {
772+
ArrayList<EsqlFunctionRegistry.ArgSignature> args = new ArrayList<>();
773+
args.add(new EsqlFunctionRegistry.ArgSignature("main", null, "Field from the main index", false, false));
774+
args.add(new EsqlFunctionRegistry.ArgSignature("join", null, "Field from the join index", false, false));
775+
DocsV3Support.CommandsDocsSupport docs = new DocsV3Support.CommandsDocsSupport(
776+
"lookup-join",
777+
LookupJoinTypesIT.class,
778+
null,
779+
args,
780+
signatures
781+
);
782+
docs.renderDocs();
783+
}
750784
}

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,23 +836,45 @@ void renderDetailedDescription(String detailedDescription, String note) throws I
836836
/** Command specific docs generating, currently very empty since we only render kibana definition files */
837837
public static class CommandsDocsSupport extends DocsV3Support {
838838
private final LogicalPlan command;
839+
private List<EsqlFunctionRegistry.ArgSignature> args;
839840
private final XPackLicenseState licenseState;
840841

842+
/** Used in CommandLicenseTests to generate Kibana docs with licensing information for commands */
841843
public CommandsDocsSupport(String name, Class<?> testClass, LogicalPlan command, XPackLicenseState licenseState) {
842844
super("commands", name, testClass, Map::of);
843845
this.command = command;
844846
this.licenseState = licenseState;
845847
}
846848

849+
/** Used in LookupJoinTypesIT to generate table of supported types for join field */
850+
public CommandsDocsSupport(
851+
String name,
852+
Class<?> testClass,
853+
LogicalPlan command,
854+
List<EsqlFunctionRegistry.ArgSignature> args,
855+
Supplier<Map<List<DataType>, DataType>> signatures
856+
) {
857+
super("commands", name, testClass, signatures);
858+
this.command = command;
859+
this.args = args;
860+
this.licenseState = null;
861+
}
862+
847863
@Override
848864
public void renderSignature() throws IOException {
849865
// Unimplemented until we make command docs dynamically generated
850866
}
851867

852868
@Override
853869
public void renderDocs() throws Exception {
854-
// Currently we only render kibana definition files, but we could expand to rendering much more if we decide to
855-
renderKibanaCommandDefinition();
870+
// Currently we only render either signatures or kibana definition files,
871+
// but we could expand to rendering much more if we decide to
872+
if (args != null) {
873+
renderTypes(name, args);
874+
}
875+
if (licenseState != null) {
876+
renderKibanaCommandDefinition();
877+
}
856878
}
857879

858880
void renderKibanaCommandDefinition() throws Exception {

0 commit comments

Comments
 (0)