This is an automated email from the ASF dual-hosted git repository.
jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 38211a6c79 Add JOIN support to PinotQuery (#10421)
38211a6c79 is described below
commit 38211a6c795ddb27194bfa3b2c161372790bc55b
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Mon Mar 27 23:31:34 2023 -0700
Add JOIN support to PinotQuery (#10421)
---
.../requesthandler/BaseBrokerRequestHandler.java | 20 +-
.../apache/pinot/common/request/DataSource.java | 240 +++++--
.../java/org/apache/pinot/common/request/Join.java | 761 +++++++++++++++++++++
.../org/apache/pinot/common/request/JoinType.java | 67 ++
.../apache/pinot/sql/parsers/CalciteSqlParser.java | 65 +-
.../pinot/sql/parsers/CalciteSqlCompilerTest.java | 122 +++-
pinot-common/src/thrift/query.thrift | 39 +-
7 files changed, 1227 insertions(+), 87 deletions(-)
diff --git
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
index 7112e0ee58..6fe32d6031 100644
---
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
+++
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
@@ -57,6 +57,7 @@ import org.apache.pinot.common.metrics.BrokerMetrics;
import org.apache.pinot.common.metrics.BrokerQueryPhase;
import org.apache.pinot.common.metrics.BrokerTimer;
import org.apache.pinot.common.request.BrokerRequest;
+import org.apache.pinot.common.request.DataSource;
import org.apache.pinot.common.request.Expression;
import org.apache.pinot.common.request.ExpressionType;
import org.apache.pinot.common.request.Function;
@@ -305,12 +306,25 @@ public abstract class BaseBrokerRequestHandler implements
BrokerRequestHandler {
}
PinotQuery serverPinotQuery = GapfillUtils.stripGapfill(pinotQuery);
- if (serverPinotQuery.getDataSource() == null) {
+ DataSource dataSource = serverPinotQuery.getDataSource();
+ if (dataSource == null) {
LOGGER.info("Data source (FROM clause) not found in request {}: {}",
request, query);
requestContext.setErrorCode(QueryException.QUERY_VALIDATION_ERROR_CODE);
return new BrokerResponseNative(
QueryException.getException(QueryException.QUERY_VALIDATION_ERROR,
"Data source (FROM clause) not found"));
}
+ if (dataSource.getJoin() != null) {
+ LOGGER.info("JOIN is not supported in request {}: {}", request, query);
+
requestContext.setErrorCode(QueryException.QUERY_VALIDATION_ERROR_CODE);
+ return new BrokerResponseNative(
+ QueryException.getException(QueryException.QUERY_VALIDATION_ERROR,
"JOIN is not supported"));
+ }
+ if (dataSource.getTableName() == null) {
+ LOGGER.info("Table name not found in request {}: {}", request, query);
+
requestContext.setErrorCode(QueryException.QUERY_VALIDATION_ERROR_CODE);
+ return new BrokerResponseNative(
+ QueryException.getException(QueryException.QUERY_VALIDATION_ERROR,
"Table name not found"));
+ }
try {
handleSubquery(serverPinotQuery, requestId, request,
requesterIdentity, requestContext);
@@ -321,8 +335,8 @@ public abstract class BaseBrokerRequestHandler implements
BrokerRequestHandler {
return new
BrokerResponseNative(QueryException.getException(QueryException.QUERY_EXECUTION_ERROR,
e));
}
- String tableName =
getActualTableName(serverPinotQuery.getDataSource().getTableName(),
_tableCache);
- serverPinotQuery.getDataSource().setTableName(tableName);
+ String tableName = getActualTableName(dataSource.getTableName(),
_tableCache);
+ dataSource.setTableName(tableName);
String rawTableName = TableNameBuilder.extractRawTableName(tableName);
requestContext.setTableName(rawTableName);
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
b/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
index e4174c5613..c6f4864ccb 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
@@ -17,7 +17,7 @@
* under the License.
*/
/**
- * Autogenerated by Thrift Compiler (0.17.0)
+ * Autogenerated by Thrift Compiler (0.15.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
@@ -25,25 +25,34 @@
package org.apache.pinot.common.request;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
[email protected](value = "Autogenerated by Thrift Compiler
(0.17.0)", date = "2023-02-08")
-public class DataSource implements org.apache.thrift.TBase<DataSource,
DataSource._Fields>, java.io.Serializable, Cloneable, Comparable<DataSource> {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new
org.apache.thrift.protocol.TStruct("DataSource");
-
- private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC
= new org.apache.thrift.protocol.TField("tableName",
org.apache.thrift.protocol.TType.STRING, (short)1);
- private static final org.apache.thrift.protocol.TField SUBQUERY_FIELD_DESC =
new org.apache.thrift.protocol.TField("subquery",
org.apache.thrift.protocol.TType.STRUCT, (short)2);
-
- private static final org.apache.thrift.scheme.SchemeFactory
STANDARD_SCHEME_FACTORY = new DataSourceStandardSchemeFactory();
[email protected](value = "Autogenerated by Thrift Compiler
(0.15.0)", date = "2023-03-14")
+public class DataSource
+ implements org.apache.thrift.TBase<DataSource, DataSource._Fields>,
java.io.Serializable, Cloneable,
+ Comparable<DataSource> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC =
+ new org.apache.thrift.protocol.TStruct("DataSource");
+
+ private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC
=
+ new org.apache.thrift.protocol.TField("tableName",
org.apache.thrift.protocol.TType.STRING, (short) 1);
+ private static final org.apache.thrift.protocol.TField SUBQUERY_FIELD_DESC =
+ new org.apache.thrift.protocol.TField("subquery",
org.apache.thrift.protocol.TType.STRUCT, (short) 2);
+ private static final org.apache.thrift.protocol.TField JOIN_FIELD_DESC =
+ new org.apache.thrift.protocol.TField("join",
org.apache.thrift.protocol.TType.STRUCT, (short) 3);
+
+ private static final org.apache.thrift.scheme.SchemeFactory
STANDARD_SCHEME_FACTORY =
+ new DataSourceStandardSchemeFactory();
private static final org.apache.thrift.scheme.SchemeFactory
TUPLE_SCHEME_FACTORY = new DataSourceTupleSchemeFactory();
public @org.apache.thrift.annotation.Nullable java.lang.String tableName; //
optional
public @org.apache.thrift.annotation.Nullable PinotQuery subquery; //
optional
+ public @org.apache.thrift.annotation.Nullable Join join; // optional
/** The set of fields this struct contains, along with convenience methods
for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- TABLE_NAME((short)1, "tableName"),
- SUBQUERY((short)2, "subquery");
+ TABLE_NAME((short) 1, "tableName"), SUBQUERY((short) 2, "subquery"),
JOIN((short) 3, "join");
- private static final java.util.Map<java.lang.String, _Fields> byName = new
java.util.HashMap<java.lang.String, _Fields>();
+ private static final java.util.Map<java.lang.String, _Fields> byName =
+ new java.util.HashMap<java.lang.String, _Fields>();
static {
for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
@@ -56,11 +65,13 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
*/
@org.apache.thrift.annotation.Nullable
public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
+ switch (fieldId) {
case 1: // TABLE_NAME
return TABLE_NAME;
case 2: // SUBQUERY
return SUBQUERY;
+ case 3: // JOIN
+ return JOIN;
default:
return null;
}
@@ -72,7 +83,9 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
*/
public static _Fields findByThriftIdOrThrow(int fieldId) {
_Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new java.lang.IllegalArgumentException("Field
" + fieldId + " doesn't exist!");
+ if (fields == null) {
+ throw new java.lang.IllegalArgumentException("Field " + fieldId + "
doesn't exist!");
+ }
return fields;
}
@@ -104,14 +117,21 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
// isset id assignments
- private static final _Fields optionals[] =
{_Fields.TABLE_NAME,_Fields.SUBQUERY};
+ private static final _Fields optionals[] = {_Fields.TABLE_NAME,
_Fields.SUBQUERY, _Fields.JOIN};
public static final java.util.Map<_Fields,
org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+
static {
- java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap =
new java.util.EnumMap<_Fields,
org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.TABLE_NAME, new
org.apache.thrift.meta_data.FieldMetaData("tableName",
org.apache.thrift.TFieldRequirementType.OPTIONAL,
- new
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
- tmpMap.put(_Fields.SUBQUERY, new
org.apache.thrift.meta_data.FieldMetaData("subquery",
org.apache.thrift.TFieldRequirementType.OPTIONAL,
- new
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
PinotQuery.class)));
+ java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap =
+ new java.util.EnumMap<_Fields,
org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.TABLE_NAME,
+ new org.apache.thrift.meta_data.FieldMetaData("tableName",
org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.SUBQUERY,
+ new org.apache.thrift.meta_data.FieldMetaData("subquery",
org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
PinotQuery.class)));
+ tmpMap.put(_Fields.JOIN,
+ new org.apache.thrift.meta_data.FieldMetaData("join",
org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT,
"Join")));
metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DataSource.class,
metaDataMap);
}
@@ -129,6 +149,9 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
if (other.isSetSubquery()) {
this.subquery = new PinotQuery(other.subquery);
}
+ if (other.isSetJoin()) {
+ this.join = new Join(other.join);
+ }
}
@Override
@@ -140,6 +163,7 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
public void clear() {
this.tableName = null;
this.subquery = null;
+ this.join = null;
}
@org.apache.thrift.annotation.Nullable
@@ -192,6 +216,31 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
}
+ @org.apache.thrift.annotation.Nullable
+ public Join getJoin() {
+ return this.join;
+ }
+
+ public DataSource setJoin(@org.apache.thrift.annotation.Nullable Join join) {
+ this.join = join;
+ return this;
+ }
+
+ public void unsetJoin() {
+ this.join = null;
+ }
+
+ /** Returns true if field join is set (has been assigned a value) and false
otherwise */
+ public boolean isSetJoin() {
+ return this.join != null;
+ }
+
+ public void setJoinIsSet(boolean value) {
+ if (!value) {
+ this.join = null;
+ }
+ }
+
@Override
public void setFieldValue(_Fields field,
@org.apache.thrift.annotation.Nullable java.lang.Object value) {
switch (field) {
@@ -199,7 +248,7 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
if (value == null) {
unsetTableName();
} else {
- setTableName((java.lang.String)value);
+ setTableName((java.lang.String) value);
}
break;
@@ -207,10 +256,17 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
if (value == null) {
unsetSubquery();
} else {
- setSubquery((PinotQuery)value);
+ setSubquery((PinotQuery) value);
}
break;
+ case JOIN:
+ if (value == null) {
+ unsetJoin();
+ } else {
+ setJoin((Join) value);
+ }
+ break;
}
}
@@ -224,6 +280,8 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
case SUBQUERY:
return getSubquery();
+ case JOIN:
+ return getJoin();
}
throw new java.lang.IllegalStateException();
}
@@ -240,39 +298,59 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
return isSetTableName();
case SUBQUERY:
return isSetSubquery();
+ case JOIN:
+ return isSetJoin();
}
throw new java.lang.IllegalStateException();
}
@Override
public boolean equals(java.lang.Object that) {
- if (that instanceof DataSource)
- return this.equals((DataSource)that);
+ if (that instanceof DataSource) {
+ return this.equals((DataSource) that);
+ }
return false;
}
public boolean equals(DataSource that) {
- if (that == null)
+ if (that == null) {
return false;
- if (this == that)
+ }
+ if (this == that) {
return true;
+ }
boolean this_present_tableName = true && this.isSetTableName();
boolean that_present_tableName = true && that.isSetTableName();
if (this_present_tableName || that_present_tableName) {
- if (!(this_present_tableName && that_present_tableName))
+ if (!(this_present_tableName && that_present_tableName)) {
return false;
- if (!this.tableName.equals(that.tableName))
+ }
+ if (!this.tableName.equals(that.tableName)) {
return false;
+ }
}
boolean this_present_subquery = true && this.isSetSubquery();
boolean that_present_subquery = true && that.isSetSubquery();
if (this_present_subquery || that_present_subquery) {
- if (!(this_present_subquery && that_present_subquery))
+ if (!(this_present_subquery && that_present_subquery)) {
+ return false;
+ }
+ if (!this.subquery.equals(that.subquery)) {
+ return false;
+ }
+ }
+
+ boolean this_present_join = true && this.isSetJoin();
+ boolean that_present_join = true && that.isSetJoin();
+ if (this_present_join || that_present_join) {
+ if (!(this_present_join && that_present_join)) {
return false;
- if (!this.subquery.equals(that.subquery))
+ }
+ if (!this.join.equals(that.join)) {
return false;
+ }
}
return true;
@@ -283,12 +361,19 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
int hashCode = 1;
hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
- if (isSetTableName())
+ if (isSetTableName()) {
hashCode = hashCode * 8191 + tableName.hashCode();
+ }
hashCode = hashCode * 8191 + ((isSetSubquery()) ? 131071 : 524287);
- if (isSetSubquery())
+ if (isSetSubquery()) {
hashCode = hashCode * 8191 + subquery.hashCode();
+ }
+
+ hashCode = hashCode * 8191 + ((isSetJoin()) ? 131071 : 524287);
+ if (isSetJoin()) {
+ hashCode = hashCode * 8191 + join.hashCode();
+ }
return hashCode;
}
@@ -321,6 +406,16 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
return lastComparison;
}
}
+ lastComparison = java.lang.Boolean.compare(isSetJoin(), other.isSetJoin());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetJoin()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.join,
other.join);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
return 0;
}
@@ -331,12 +426,14 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
@Override
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws
org.apache.thrift.TException {
+ public void read(org.apache.thrift.protocol.TProtocol iprot)
+ throws org.apache.thrift.TException {
scheme(iprot).read(iprot, this);
}
@Override
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws
org.apache.thrift.TException {
+ public void write(org.apache.thrift.protocol.TProtocol oprot)
+ throws org.apache.thrift.TException {
scheme(oprot).write(oprot, this);
}
@@ -355,7 +452,9 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
first = false;
}
if (isSetSubquery()) {
- if (!first) sb.append(", ");
+ if (!first) {
+ sb.append(", ");
+ }
sb.append("subquery:");
if (this.subquery == null) {
sb.append("null");
@@ -364,11 +463,24 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
first = false;
}
+ if (isSetJoin()) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("join:");
+ if (this.join == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.join);
+ }
+ first = false;
+ }
sb.append(")");
return sb.toString();
}
- public void validate() throws org.apache.thrift.TException {
+ public void validate()
+ throws org.apache.thrift.TException {
// check for required fields
// check for sub-struct validity
if (subquery != null) {
@@ -376,7 +488,8 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
}
- private void writeObject(java.io.ObjectOutputStream out) throws
java.io.IOException {
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
try {
write(new org.apache.thrift.protocol.TCompactProtocol(new
org.apache.thrift.transport.TIOStreamTransport(out)));
} catch (org.apache.thrift.TException te) {
@@ -384,7 +497,8 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
}
- private void readObject(java.io.ObjectInputStream in) throws
java.io.IOException, java.lang.ClassNotFoundException {
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, java.lang.ClassNotFoundException {
try {
read(new org.apache.thrift.protocol.TCompactProtocol(new
org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
@@ -402,11 +516,11 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
private static class DataSourceStandardScheme extends
org.apache.thrift.scheme.StandardScheme<DataSource> {
@Override
- public void read(org.apache.thrift.protocol.TProtocol iprot, DataSource
struct) throws org.apache.thrift.TException {
+ public void read(org.apache.thrift.protocol.TProtocol iprot, DataSource
struct)
+ throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
- while (true)
- {
+ while (true) {
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
@@ -429,6 +543,15 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
}
break;
+ case 3: // JOIN
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.join = new Join();
+ struct.join.read(iprot);
+ struct.setJoinIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
+ }
+ break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
}
@@ -441,7 +564,8 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
}
@Override
- public void write(org.apache.thrift.protocol.TProtocol oprot, DataSource
struct) throws org.apache.thrift.TException {
+ public void write(org.apache.thrift.protocol.TProtocol oprot, DataSource
struct)
+ throws org.apache.thrift.TException {
struct.validate();
oprot.writeStructBegin(STRUCT_DESC);
@@ -459,10 +583,16 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
oprot.writeFieldEnd();
}
}
+ if (struct.join != null) {
+ if (struct.isSetJoin()) {
+ oprot.writeFieldBegin(JOIN_FIELD_DESC);
+ struct.join.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ }
oprot.writeFieldStop();
oprot.writeStructEnd();
}
-
}
private static class DataSourceTupleSchemeFactory implements
org.apache.thrift.scheme.SchemeFactory {
@@ -475,7 +605,8 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
private static class DataSourceTupleScheme extends
org.apache.thrift.scheme.TupleScheme<DataSource> {
@Override
- public void write(org.apache.thrift.protocol.TProtocol prot, DataSource
struct) throws org.apache.thrift.TException {
+ public void write(org.apache.thrift.protocol.TProtocol prot, DataSource
struct)
+ throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol oprot =
(org.apache.thrift.protocol.TTupleProtocol) prot;
java.util.BitSet optionals = new java.util.BitSet();
if (struct.isSetTableName()) {
@@ -484,19 +615,26 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
if (struct.isSetSubquery()) {
optionals.set(1);
}
- oprot.writeBitSet(optionals, 2);
+ if (struct.isSetJoin()) {
+ optionals.set(2);
+ }
+ oprot.writeBitSet(optionals, 3);
if (struct.isSetTableName()) {
oprot.writeString(struct.tableName);
}
if (struct.isSetSubquery()) {
struct.subquery.write(oprot);
}
+ if (struct.isSetJoin()) {
+ struct.join.write(oprot);
+ }
}
@Override
- public void read(org.apache.thrift.protocol.TProtocol prot, DataSource
struct) throws org.apache.thrift.TException {
+ public void read(org.apache.thrift.protocol.TProtocol prot, DataSource
struct)
+ throws org.apache.thrift.TException {
org.apache.thrift.protocol.TTupleProtocol iprot =
(org.apache.thrift.protocol.TTupleProtocol) prot;
- java.util.BitSet incoming = iprot.readBitSet(2);
+ java.util.BitSet incoming = iprot.readBitSet(3);
if (incoming.get(0)) {
struct.tableName = iprot.readString();
struct.setTableNameIsSet(true);
@@ -506,11 +644,17 @@ public class DataSource implements
org.apache.thrift.TBase<DataSource, DataSourc
struct.subquery.read(iprot);
struct.setSubqueryIsSet(true);
}
+ if (incoming.get(2)) {
+ struct.join = new Join();
+ struct.join.read(iprot);
+ struct.setJoinIsSet(true);
+ }
}
}
private static <S extends org.apache.thrift.scheme.IScheme> S
scheme(org.apache.thrift.protocol.TProtocol proto) {
- return
(org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ?
STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+ return
(org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ?
STANDARD_SCHEME_FACTORY
+ : TUPLE_SCHEME_FACTORY).getScheme();
}
}
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java
b/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java
new file mode 100644
index 0000000000..b618ad4047
--- /dev/null
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java
@@ -0,0 +1,761 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.15.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.pinot.common.request;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
[email protected](value = "Autogenerated by Thrift Compiler
(0.15.0)", date = "2023-03-14")
+public class Join
+ implements org.apache.thrift.TBase<Join, Join._Fields>,
java.io.Serializable, Cloneable, Comparable<Join> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new
org.apache.thrift.protocol.TStruct("Join");
+
+ private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC =
+ new org.apache.thrift.protocol.TField("type",
org.apache.thrift.protocol.TType.I32, (short) 1);
+ private static final org.apache.thrift.protocol.TField LEFT_FIELD_DESC =
+ new org.apache.thrift.protocol.TField("left",
org.apache.thrift.protocol.TType.STRUCT, (short) 2);
+ private static final org.apache.thrift.protocol.TField RIGHT_FIELD_DESC =
+ new org.apache.thrift.protocol.TField("right",
org.apache.thrift.protocol.TType.STRUCT, (short) 3);
+ private static final org.apache.thrift.protocol.TField CONDITION_FIELD_DESC =
+ new org.apache.thrift.protocol.TField("condition",
org.apache.thrift.protocol.TType.STRUCT, (short) 4);
+
+ private static final org.apache.thrift.scheme.SchemeFactory
STANDARD_SCHEME_FACTORY = new JoinStandardSchemeFactory();
+ private static final org.apache.thrift.scheme.SchemeFactory
TUPLE_SCHEME_FACTORY = new JoinTupleSchemeFactory();
+
+ public @org.apache.thrift.annotation.Nullable JoinType type; // required
+ public @org.apache.thrift.annotation.Nullable DataSource left; // required
+ public @org.apache.thrift.annotation.Nullable DataSource right; // required
+ public @org.apache.thrift.annotation.Nullable Expression condition; //
optional
+
+ /** The set of fields this struct contains, along with convenience methods
for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ TYPE((short) 1, "type"), LEFT((short) 2, "left"), RIGHT((short) 3,
"right"), CONDITION((short) 4, "condition");
+
+ private static final java.util.Map<java.lang.String, _Fields> byName =
+ new java.util.HashMap<java.lang.String, _Fields>();
+
+ static {
+ for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not
found.
+ */
+ @org.apache.thrift.annotation.Nullable
+ public static _Fields findByThriftId(int fieldId) {
+ switch (fieldId) {
+ case 1: // TYPE
+ return TYPE;
+ case 2: // LEFT
+ return LEFT;
+ case 3: // RIGHT
+ return RIGHT;
+ case 4: // CONDITION
+ return CONDITION;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) {
+ throw new java.lang.IllegalArgumentException("Field " + fieldId + "
doesn't exist!");
+ }
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ @org.apache.thrift.annotation.Nullable
+ public static _Fields findByName(java.lang.String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final java.lang.String _fieldName;
+
+ _Fields(short thriftId, java.lang.String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ @Override
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ @Override
+ public java.lang.String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ private static final _Fields optionals[] = {_Fields.CONDITION};
+ public static final java.util.Map<_Fields,
org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+
+ static {
+ java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap =
+ new java.util.EnumMap<_Fields,
org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.TYPE,
+ new org.apache.thrift.meta_data.FieldMetaData("type",
org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.ENUM,
"JoinType")));
+ tmpMap.put(_Fields.LEFT,
+ new org.apache.thrift.meta_data.FieldMetaData("left",
org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
DataSource.class)));
+ tmpMap.put(_Fields.RIGHT,
+ new org.apache.thrift.meta_data.FieldMetaData("right",
org.apache.thrift.TFieldRequirementType.REQUIRED,
+ new
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
DataSource.class)));
+ tmpMap.put(_Fields.CONDITION,
+ new org.apache.thrift.meta_data.FieldMetaData("condition",
org.apache.thrift.TFieldRequirementType.OPTIONAL,
+ new
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT,
"Expression")));
+ metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Join.class,
metaDataMap);
+ }
+
+ public Join() {
+ }
+
+ public Join(JoinType type, DataSource left, DataSource right) {
+ this();
+ this.type = type;
+ this.left = left;
+ this.right = right;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public Join(Join other) {
+ if (other.isSetType()) {
+ this.type = other.type;
+ }
+ if (other.isSetLeft()) {
+ this.left = new DataSource(other.left);
+ }
+ if (other.isSetRight()) {
+ this.right = new DataSource(other.right);
+ }
+ if (other.isSetCondition()) {
+ this.condition = new Expression(other.condition);
+ }
+ }
+
+ @Override
+ public Join deepCopy() {
+ return new Join(this);
+ }
+
+ @Override
+ public void clear() {
+ this.type = null;
+ this.left = null;
+ this.right = null;
+ this.condition = null;
+ }
+
+ @org.apache.thrift.annotation.Nullable
+ public JoinType getType() {
+ return this.type;
+ }
+
+ public Join setType(@org.apache.thrift.annotation.Nullable JoinType type) {
+ this.type = type;
+ return this;
+ }
+
+ public void unsetType() {
+ this.type = null;
+ }
+
+ /** Returns true if field type is set (has been assigned a value) and false
otherwise */
+ public boolean isSetType() {
+ return this.type != null;
+ }
+
+ public void setTypeIsSet(boolean value) {
+ if (!value) {
+ this.type = null;
+ }
+ }
+
+ @org.apache.thrift.annotation.Nullable
+ public DataSource getLeft() {
+ return this.left;
+ }
+
+ public Join setLeft(@org.apache.thrift.annotation.Nullable DataSource left) {
+ this.left = left;
+ return this;
+ }
+
+ public void unsetLeft() {
+ this.left = null;
+ }
+
+ /** Returns true if field left is set (has been assigned a value) and false
otherwise */
+ public boolean isSetLeft() {
+ return this.left != null;
+ }
+
+ public void setLeftIsSet(boolean value) {
+ if (!value) {
+ this.left = null;
+ }
+ }
+
+ @org.apache.thrift.annotation.Nullable
+ public DataSource getRight() {
+ return this.right;
+ }
+
+ public Join setRight(@org.apache.thrift.annotation.Nullable DataSource
right) {
+ this.right = right;
+ return this;
+ }
+
+ public void unsetRight() {
+ this.right = null;
+ }
+
+ /** Returns true if field right is set (has been assigned a value) and false
otherwise */
+ public boolean isSetRight() {
+ return this.right != null;
+ }
+
+ public void setRightIsSet(boolean value) {
+ if (!value) {
+ this.right = null;
+ }
+ }
+
+ @org.apache.thrift.annotation.Nullable
+ public Expression getCondition() {
+ return this.condition;
+ }
+
+ public Join setCondition(@org.apache.thrift.annotation.Nullable Expression
condition) {
+ this.condition = condition;
+ return this;
+ }
+
+ public void unsetCondition() {
+ this.condition = null;
+ }
+
+ /** Returns true if field condition is set (has been assigned a value) and
false otherwise */
+ public boolean isSetCondition() {
+ return this.condition != null;
+ }
+
+ public void setConditionIsSet(boolean value) {
+ if (!value) {
+ this.condition = null;
+ }
+ }
+
+ @Override
+ public void setFieldValue(_Fields field,
@org.apache.thrift.annotation.Nullable java.lang.Object value) {
+ switch (field) {
+ case TYPE:
+ if (value == null) {
+ unsetType();
+ } else {
+ setType((JoinType) value);
+ }
+ break;
+
+ case LEFT:
+ if (value == null) {
+ unsetLeft();
+ } else {
+ setLeft((DataSource) value);
+ }
+ break;
+
+ case RIGHT:
+ if (value == null) {
+ unsetRight();
+ } else {
+ setRight((DataSource) value);
+ }
+ break;
+
+ case CONDITION:
+ if (value == null) {
+ unsetCondition();
+ } else {
+ setCondition((Expression) value);
+ }
+ break;
+ }
+ }
+
+ @org.apache.thrift.annotation.Nullable
+ @Override
+ public java.lang.Object getFieldValue(_Fields field) {
+ switch (field) {
+ case TYPE:
+ return getType();
+
+ case LEFT:
+ return getLeft();
+
+ case RIGHT:
+ return getRight();
+
+ case CONDITION:
+ return getCondition();
+ }
+ throw new java.lang.IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned
a value) and false otherwise */
+ @Override
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new java.lang.IllegalArgumentException();
+ }
+
+ switch (field) {
+ case TYPE:
+ return isSetType();
+ case LEFT:
+ return isSetLeft();
+ case RIGHT:
+ return isSetRight();
+ case CONDITION:
+ return isSetCondition();
+ }
+ throw new java.lang.IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(java.lang.Object that) {
+ if (that instanceof Join) {
+ return this.equals((Join) that);
+ }
+ return false;
+ }
+
+ public boolean equals(Join that) {
+ if (that == null) {
+ return false;
+ }
+ if (this == that) {
+ return true;
+ }
+
+ boolean this_present_type = true && this.isSetType();
+ boolean that_present_type = true && that.isSetType();
+ if (this_present_type || that_present_type) {
+ if (!(this_present_type && that_present_type)) {
+ return false;
+ }
+ if (!this.type.equals(that.type)) {
+ return false;
+ }
+ }
+
+ boolean this_present_left = true && this.isSetLeft();
+ boolean that_present_left = true && that.isSetLeft();
+ if (this_present_left || that_present_left) {
+ if (!(this_present_left && that_present_left)) {
+ return false;
+ }
+ if (!this.left.equals(that.left)) {
+ return false;
+ }
+ }
+
+ boolean this_present_right = true && this.isSetRight();
+ boolean that_present_right = true && that.isSetRight();
+ if (this_present_right || that_present_right) {
+ if (!(this_present_right && that_present_right)) {
+ return false;
+ }
+ if (!this.right.equals(that.right)) {
+ return false;
+ }
+ }
+
+ boolean this_present_condition = true && this.isSetCondition();
+ boolean that_present_condition = true && that.isSetCondition();
+ if (this_present_condition || that_present_condition) {
+ if (!(this_present_condition && that_present_condition)) {
+ return false;
+ }
+ if (!this.condition.equals(that.condition)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ hashCode = hashCode * 8191 + ((isSetType()) ? 131071 : 524287);
+ if (isSetType()) {
+ hashCode = hashCode * 8191 + type.getValue();
+ }
+
+ hashCode = hashCode * 8191 + ((isSetLeft()) ? 131071 : 524287);
+ if (isSetLeft()) {
+ hashCode = hashCode * 8191 + left.hashCode();
+ }
+
+ hashCode = hashCode * 8191 + ((isSetRight()) ? 131071 : 524287);
+ if (isSetRight()) {
+ hashCode = hashCode * 8191 + right.hashCode();
+ }
+
+ hashCode = hashCode * 8191 + ((isSetCondition()) ? 131071 : 524287);
+ if (isSetCondition()) {
+ hashCode = hashCode * 8191 + condition.hashCode();
+ }
+
+ return hashCode;
+ }
+
+ @Override
+ public int compareTo(Join other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = java.lang.Boolean.compare(isSetType(), other.isSetType());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetType()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type,
other.type);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = java.lang.Boolean.compare(isSetLeft(), other.isSetLeft());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetLeft()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.left,
other.left);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = java.lang.Boolean.compare(isSetRight(),
other.isSetRight());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetRight()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.right,
other.right);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = java.lang.Boolean.compare(isSetCondition(),
other.isSetCondition());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetCondition()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.condition,
other.condition);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ @org.apache.thrift.annotation.Nullable
+ @Override
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol iprot)
+ throws org.apache.thrift.TException {
+ scheme(iprot).read(iprot, this);
+ }
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol oprot)
+ throws org.apache.thrift.TException {
+ scheme(oprot).write(oprot, this);
+ }
+
+ @Override
+ public java.lang.String toString() {
+ java.lang.StringBuilder sb = new java.lang.StringBuilder("Join(");
+ boolean first = true;
+
+ sb.append("type:");
+ if (this.type == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.type);
+ }
+ first = false;
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("left:");
+ if (this.left == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.left);
+ }
+ first = false;
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("right:");
+ if (this.right == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.right);
+ }
+ first = false;
+ if (isSetCondition()) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append("condition:");
+ if (this.condition == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.condition);
+ }
+ first = false;
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate()
+ throws org.apache.thrift.TException {
+ // check for required fields
+ if (type == null) {
+ throw new org.apache.thrift.protocol.TProtocolException(
+ "Required field 'type' was not present! Struct: " + toString());
+ }
+ if (left == null) {
+ throw new org.apache.thrift.protocol.TProtocolException(
+ "Required field 'left' was not present! Struct: " + toString());
+ }
+ if (right == null) {
+ throw new org.apache.thrift.protocol.TProtocolException(
+ "Required field 'right' was not present! Struct: " + toString());
+ }
+ // check for sub-struct validity
+ if (left != null) {
+ left.validate();
+ }
+ if (right != null) {
+ right.validate();
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new
org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws java.io.IOException, java.lang.ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new
org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class JoinStandardSchemeFactory implements
org.apache.thrift.scheme.SchemeFactory {
+ @Override
+ public JoinStandardScheme getScheme() {
+ return new JoinStandardScheme();
+ }
+ }
+
+ private static class JoinStandardScheme extends
org.apache.thrift.scheme.StandardScheme<Join> {
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol iprot, Join struct)
+ throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true) {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // TYPE
+ if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+ struct.type =
org.apache.pinot.common.request.JoinType.findByValue(iprot.readI32());
+ struct.setTypeIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
+ }
+ break;
+ case 2: // LEFT
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.left = new DataSource();
+ struct.left.read(iprot);
+ struct.setLeftIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
+ }
+ break;
+ case 3: // RIGHT
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.right = new DataSource();
+ struct.right.read(iprot);
+ struct.setRightIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
+ }
+ break;
+ case 4: // CONDITION
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.condition = new Expression();
+ struct.condition.read(iprot);
+ struct.setConditionIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot,
schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+
+ // check for required fields of primitive type, which can't be checked
in the validate method
+ struct.validate();
+ }
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol oprot, Join struct)
+ throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.type != null) {
+ oprot.writeFieldBegin(TYPE_FIELD_DESC);
+ oprot.writeI32(struct.type.getValue());
+ oprot.writeFieldEnd();
+ }
+ if (struct.left != null) {
+ oprot.writeFieldBegin(LEFT_FIELD_DESC);
+ struct.left.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ if (struct.right != null) {
+ oprot.writeFieldBegin(RIGHT_FIELD_DESC);
+ struct.right.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ if (struct.condition != null) {
+ if (struct.isSetCondition()) {
+ oprot.writeFieldBegin(CONDITION_FIELD_DESC);
+ struct.condition.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+ }
+
+ private static class JoinTupleSchemeFactory implements
org.apache.thrift.scheme.SchemeFactory {
+ @Override
+ public JoinTupleScheme getScheme() {
+ return new JoinTupleScheme();
+ }
+ }
+
+ private static class JoinTupleScheme extends
org.apache.thrift.scheme.TupleScheme<Join> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, Join struct)
+ throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TTupleProtocol oprot =
(org.apache.thrift.protocol.TTupleProtocol) prot;
+ oprot.writeI32(struct.type.getValue());
+ struct.left.write(oprot);
+ struct.right.write(oprot);
+ java.util.BitSet optionals = new java.util.BitSet();
+ if (struct.isSetCondition()) {
+ optionals.set(0);
+ }
+ oprot.writeBitSet(optionals, 1);
+ if (struct.isSetCondition()) {
+ struct.condition.write(oprot);
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, Join struct)
+ throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TTupleProtocol iprot =
(org.apache.thrift.protocol.TTupleProtocol) prot;
+ struct.type =
org.apache.pinot.common.request.JoinType.findByValue(iprot.readI32());
+ struct.setTypeIsSet(true);
+ struct.left = new DataSource();
+ struct.left.read(iprot);
+ struct.setLeftIsSet(true);
+ struct.right = new DataSource();
+ struct.right.read(iprot);
+ struct.setRightIsSet(true);
+ java.util.BitSet incoming = iprot.readBitSet(1);
+ if (incoming.get(0)) {
+ struct.condition = new Expression();
+ struct.condition.read(iprot);
+ struct.setConditionIsSet(true);
+ }
+ }
+ }
+
+ private static <S extends org.apache.thrift.scheme.IScheme> S
scheme(org.apache.thrift.protocol.TProtocol proto) {
+ return
(org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ?
STANDARD_SCHEME_FACTORY
+ : TUPLE_SCHEME_FACTORY).getScheme();
+ }
+}
+
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java
b/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java
new file mode 100644
index 0000000000..08efcf21bb
--- /dev/null
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.15.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package org.apache.pinot.common.request;
+
+
[email protected](value = "Autogenerated by Thrift Compiler
(0.15.0)", date = "2023-03-14")
+public enum JoinType implements org.apache.thrift.TEnum {
+ INNER(0),
+ LEFT(1),
+ RIGHT(2),
+ FULL(3);
+
+ private final int value;
+
+ private JoinType(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the integer value of this enum value, as defined in the Thrift IDL.
+ */
+ public int getValue() {
+ return value;
+ }
+
+ /**
+ * Find a the enum type by its integer value, as defined in the Thrift IDL.
+ * @return null if the value is not found.
+ */
+ @org.apache.thrift.annotation.Nullable
+ public static JoinType findByValue(int value) {
+ switch (value) {
+ case 0:
+ return INNER;
+ case 1:
+ return LEFT;
+ case 2:
+ return RIGHT;
+ case 3:
+ return FULL;
+ default:
+ return null;
+ }
+ }
+}
diff --git
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
index 27cf9b77be..237f0eb496 100644
---
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
+++
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
@@ -61,6 +61,8 @@ import org.apache.pinot.common.request.Expression;
import org.apache.pinot.common.request.ExpressionType;
import org.apache.pinot.common.request.Function;
import org.apache.pinot.common.request.Identifier;
+import org.apache.pinot.common.request.Join;
+import org.apache.pinot.common.request.JoinType;
import org.apache.pinot.common.request.PinotQuery;
import org.apache.pinot.common.utils.config.QueryOptionsUtils;
import org.apache.pinot.common.utils.request.RequestUtils;
@@ -450,12 +452,7 @@ public class CalciteSqlParser {
// FROM
SqlNode fromNode = selectNode.getFrom();
if (fromNode != null) {
- DataSource dataSource = new DataSource();
- dataSource.setTableName(fromNode.toString());
- pinotQuery.setDataSource(dataSource);
- if (fromNode instanceof SqlSelect || fromNode instanceof SqlOrderBy) {
- dataSource.setSubquery(compileSqlNodeToPinotQuery(fromNode));
- }
+ pinotQuery.setDataSource(compileToDataSource(fromNode));
}
// WHERE
SqlNode whereNode = selectNode.getWhere();
@@ -492,6 +489,62 @@ public class CalciteSqlParser {
return pinotQuery;
}
+ private static DataSource compileToDataSource(SqlNode sqlNode) {
+ DataSource dataSource = new DataSource();
+ switch (sqlNode.getKind()) {
+ case IDENTIFIER:
+ dataSource.setTableName(sqlNode.toString());
+ break;
+ case AS:
+ List<SqlNode> operandList = ((SqlBasicCall) sqlNode).getOperandList();
+ dataSource.setSubquery(compileSqlNodeToPinotQuery(operandList.get(0)));
+ dataSource.setTableName(operandList.get(1).toString());
+ break;
+ case SELECT:
+ case ORDER_BY:
+ dataSource.setSubquery(compileSqlNodeToPinotQuery(sqlNode));
+ break;
+ case JOIN:
+ dataSource.setJoin(compileToJoin((SqlJoin) sqlNode));
+ break;
+ default:
+ throw new IllegalStateException("Unsupported SQL node kind as
DataSource: " + sqlNode.getKind());
+ }
+ return dataSource;
+ }
+
+ private static Join compileToJoin(SqlJoin sqlJoin) {
+ Join join = new Join();
+ switch (sqlJoin.getJoinType()) {
+ case INNER:
+ join.setType(JoinType.INNER);
+ break;
+ case LEFT:
+ join.setType(JoinType.LEFT);
+ break;
+ case RIGHT:
+ join.setType(JoinType.RIGHT);
+ break;
+ case FULL:
+ join.setType(JoinType.FULL);
+ break;
+ default:
+ throw new IllegalStateException("Unsupported join type: " +
sqlJoin.getJoinType());
+ }
+ join.setLeft(compileToDataSource(sqlJoin.getLeft()));
+ join.setRight(compileToDataSource(sqlJoin.getRight()));
+ switch (sqlJoin.getConditionType()) {
+ case ON:
+ join.setCondition(toExpression(sqlJoin.getCondition()));
+ break;
+ case NONE:
+ break;
+ default:
+ throw new IllegalStateException("Unsupported join condition type: " +
sqlJoin.getConditionType());
+ }
+ return join;
+ }
+
private static void queryRewrite(PinotQuery pinotQuery) {
for (QueryRewriter queryRewriter : QUERY_REWRITERS) {
pinotQuery = queryRewriter.rewrite(pinotQuery);
diff --git
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
index f97257336c..9ac05dd985 100644
---
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
+++
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
@@ -27,10 +27,13 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlNumericLiteral;
+import org.apache.pinot.common.request.DataSource;
import org.apache.pinot.common.request.Expression;
import org.apache.pinot.common.request.ExpressionType;
import org.apache.pinot.common.request.Function;
import org.apache.pinot.common.request.Identifier;
+import org.apache.pinot.common.request.Join;
+import org.apache.pinot.common.request.JoinType;
import org.apache.pinot.common.request.Literal;
import org.apache.pinot.common.request.PinotQuery;
import org.apache.pinot.common.utils.request.RequestUtils;
@@ -1831,7 +1834,7 @@ public class CalciteSqlCompilerTest {
"distinct_bar");
query = "SELECT sum(distinct bar) AS distinct_bar, count(*),
sum(a),min(a),max(b) FROM foo GROUP BY city ORDER BY "
- + "distinct_bar";
+ + "distinct_bar";
pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
Assert.assertEquals(pinotQuery.getSelectList().size(), 5);
Function selectFunctionCall =
pinotQuery.getSelectList().get(0).getFunctionCall();
@@ -2239,9 +2242,8 @@ public class CalciteSqlCompilerTest {
result = pinotQuery.getSelectList().get(0).getLiteral().getBoolValue();
Assert.assertTrue(result);
- query =
- "select isSubnetOf('2001:db8:85a3::8a2e:370:7334/62',
'2001:0db8:85a3:0003:ffff:ffff:ffff:ffff') from "
- + "mytable";
+ query = "select isSubnetOf('2001:db8:85a3::8a2e:370:7334/62',
'2001:0db8:85a3:0003:ffff:ffff:ffff:ffff') from "
+ + "mytable";
pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
result = pinotQuery.getSelectList().get(0).getLiteral().getBoolValue();
Assert.assertTrue(result);
@@ -2949,13 +2951,24 @@ public class CalciteSqlCompilerTest {
* Test for customized components in src/main/codegen/parserImpls.ftl file.
*/
@Test
- public void testParserExtensionImpl() {
+ public void testParserExtensionImpl()
+ throws Exception {
String customSql = "INSERT INTO db.tbl FROM FILE 'file:///tmp/file1', FILE
'file:///tmp/file2'";
SqlNodeAndOptions sqlNodeAndOptions =
testSqlWithCustomSqlParser(customSql);
Assert.assertTrue(sqlNodeAndOptions.getSqlNode() instanceof
SqlInsertFromFile);
Assert.assertEquals(sqlNodeAndOptions.getSqlType(), PinotSqlType.DML);
}
+ private static SqlNodeAndOptions testSqlWithCustomSqlParser(String sqlString)
+ throws Exception {
+ try (StringReader inStream = new StringReader(sqlString)) {
+ SqlParserImpl sqlParser = CalciteSqlParser.newSqlParser(inStream);
+ SqlNodeList sqlNodeList = sqlParser.SqlStmtsEof();
+ // Extract OPTION statements from sql.
+ return CalciteSqlParser.extractSqlNodeAndOptions(sqlString, sqlNodeList);
+ }
+ }
+
@Test
public void shouldParseBasicAtTimeZoneExtension() {
// Given:
@@ -3023,7 +3036,7 @@ public class CalciteSqlCompilerTest {
// query with IN / NOT IN clause
query = "SELECT COUNT(*) FROM tbl1 WHERE userUUID IN (SELECT userUUID FROM
tbl2) "
- + "and uuid NOT IN (SELECT uuid from tbl3)";
+ + "and uuid NOT IN (SELECT uuid from tbl3)";
sqlNodeAndOptions = RequestUtils.parseQuery(query);
tableNames =
CalciteSqlParser.extractTableNamesFromNode(sqlNodeAndOptions.getSqlNode());
Assert.assertEquals(tableNames.size(), 3);
@@ -3043,8 +3056,8 @@ public class CalciteSqlCompilerTest {
// query with aliases, JOIN, IN/NOT-IN, group-by
query = "with tmp as (select col1, count(*) from tbl1 where condition1 =
filter1 group by col1), "
- + "tmp2 as (select A.col1, B.col2 from tbl2 as A JOIN tbl3 AS B on
A.key = B.key) "
- + "select sum(col1) from tmp where col1 in (select col1 from tmp2)
and col1 not in (select col1 from tbl4)";
+ + "tmp2 as (select A.col1, B.col2 from tbl2 as A JOIN tbl3 AS B on
A.key = B.key) "
+ + "select sum(col1) from tmp where col1 in (select col1 from tmp2) and
col1 not in (select col1 from tbl4)";
sqlNodeAndOptions = RequestUtils.parseQuery(query);
tableNames =
CalciteSqlParser.extractTableNamesFromNode(sqlNodeAndOptions.getSqlNode());
Assert.assertEquals(tableNames.size(), 4);
@@ -3054,15 +3067,88 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(tableNames.get(3), "tbl4");
}
- private static SqlNodeAndOptions testSqlWithCustomSqlParser(String
sqlString) {
- try (StringReader inStream = new StringReader(sqlString)) {
- SqlParserImpl sqlParser = CalciteSqlParser.newSqlParser(inStream);
- SqlNodeList sqlNodeList = sqlParser.SqlStmtsEof();
- // Extract OPTION statements from sql.
- return CalciteSqlParser.extractSqlNodeAndOptions(sqlString, sqlNodeList);
- } catch (Exception e) {
- Assert.fail("test custom sql parser failed", e);
- return null;
- }
+ @Test
+ public void testJoin() {
+ String query = "SELECT T1.a, T2.b FROM T1 JOIN T2";
+ PinotQuery pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+ DataSource dataSource = pinotQuery.getDataSource();
+ Assert.assertNull(dataSource.getTableName());
+ Assert.assertNull(dataSource.getSubquery());
+ Assert.assertNotNull(dataSource.getJoin());
+ Join join = dataSource.getJoin();
+ Assert.assertEquals(join.getType(), JoinType.INNER);
+ Assert.assertEquals(join.getLeft().getTableName(), "T1");
+ Assert.assertEquals(join.getRight().getTableName(), "T2");
+ Assert.assertNull(join.getCondition());
+
+ query = "SELECT T1.a, T2.b FROM T1 INNER JOIN T2 ON T1.key = T2.key";
+ pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+ dataSource = pinotQuery.getDataSource();
+ Assert.assertNull(dataSource.getTableName());
+ Assert.assertNull(dataSource.getSubquery());
+ Assert.assertNotNull(dataSource.getJoin());
+ join = dataSource.getJoin();
+ Assert.assertEquals(join.getType(), JoinType.INNER);
+ Assert.assertEquals(join.getLeft().getTableName(), "T1");
+ Assert.assertEquals(join.getRight().getTableName(), "T2");
+ Assert.assertEquals(join.getCondition(),
CalciteSqlParser.compileToExpression("T1.key = T2.key"));
+
+ query = "SELECT T1.a, T2.b FROM T1 FULL JOIN T2 ON T1.key = T2.key";
+ pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+ dataSource = pinotQuery.getDataSource();
+ Assert.assertNull(dataSource.getTableName());
+ Assert.assertNull(dataSource.getSubquery());
+ Assert.assertNotNull(dataSource.getJoin());
+ join = dataSource.getJoin();
+ Assert.assertEquals(join.getType(), JoinType.FULL);
+ Assert.assertEquals(join.getLeft().getTableName(), "T1");
+ Assert.assertEquals(join.getRight().getTableName(), "T2");
+ Assert.assertEquals(join.getCondition(),
CalciteSqlParser.compileToExpression("T1.key = T2.key"));
+
+ query = "SELECT T1.a, T2.b FROM T1 LEFT JOIN T2 ON T1.a > T2.b";
+ pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+ dataSource = pinotQuery.getDataSource();
+ Assert.assertNull(dataSource.getTableName());
+ Assert.assertNull(dataSource.getSubquery());
+ Assert.assertNotNull(dataSource.getJoin());
+ join = dataSource.getJoin();
+ Assert.assertEquals(join.getType(), JoinType.LEFT);
+ Assert.assertEquals(join.getLeft().getTableName(), "T1");
+ Assert.assertEquals(join.getRight().getTableName(), "T2");
+ Assert.assertEquals(join.getCondition(),
CalciteSqlParser.compileToExpression("T1.a > T2.b"));
+
+ query =
+ "SELECT T1.a, T2.b FROM T1 RIGHT JOIN (SELECT a, COUNT(*) AS b FROM T3
GROUP BY a) AS T2 ON T1.key = T2.key";
+ pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+ dataSource = pinotQuery.getDataSource();
+ Assert.assertNull(dataSource.getTableName());
+ Assert.assertNull(dataSource.getSubquery());
+ Assert.assertNotNull(dataSource.getJoin());
+ join = dataSource.getJoin();
+ Assert.assertEquals(join.getType(), JoinType.RIGHT);
+ Assert.assertEquals(join.getLeft().getTableName(), "T1");
+ DataSource right = join.getRight();
+ Assert.assertEquals(right.getTableName(), "T2");
+ PinotQuery rightSubquery = right.getSubquery();
+ Assert.assertEquals(rightSubquery,
+ CalciteSqlParser.compileToPinotQuery("SELECT a, COUNT(*) AS b FROM T3
GROUP BY a"));
+ Assert.assertEquals(join.getCondition(),
CalciteSqlParser.compileToExpression("T1.key = T2.key"));
+
+ query = "SELECT T1.a, T2.b FROM T1 JOIN (SELECT key, COUNT(*) AS b FROM T3
JOIN T4 GROUP BY key) AS T2 "
+ + "ON T1.key = T2.key";
+ pinotQuery = CalciteSqlParser.compileToPinotQuery(query);
+ dataSource = pinotQuery.getDataSource();
+ Assert.assertNull(dataSource.getTableName());
+ Assert.assertNull(dataSource.getSubquery());
+ Assert.assertNotNull(dataSource.getJoin());
+ join = dataSource.getJoin();
+ Assert.assertEquals(join.getType(), JoinType.INNER);
+ Assert.assertEquals(join.getLeft().getTableName(), "T1");
+ right = join.getRight();
+ Assert.assertEquals(right.getTableName(), "T2");
+ rightSubquery = right.getSubquery();
+ Assert.assertEquals(rightSubquery,
+ CalciteSqlParser.compileToPinotQuery("SELECT key, COUNT(*) AS b FROM
T3 JOIN T4 GROUP BY key"));
+ Assert.assertEquals(join.getCondition(),
CalciteSqlParser.compileToExpression("T1.key = T2.key"));
}
}
diff --git a/pinot-common/src/thrift/query.thrift
b/pinot-common/src/thrift/query.thrift
index a2db738c36..12a601c2df 100644
--- a/pinot-common/src/thrift/query.thrift
+++ b/pinot-common/src/thrift/query.thrift
@@ -18,11 +18,6 @@
*/
namespace java org.apache.pinot.common.request
-struct DataSource {
- 1: optional string tableName;
- 2: optional PinotQuery subquery;
-}
-
struct PinotQuery {
1: optional i32 version;
2: optional DataSource dataSource;
@@ -39,10 +34,24 @@ struct PinotQuery {
13: optional map<Expression, Expression> expressionOverrideHints;
}
-enum ExpressionType {
- LITERAL,
- IDENTIFIER,
- FUNCTION
+struct DataSource {
+ 1: optional string tableName;
+ 2: optional PinotQuery subquery;
+ 3: optional Join join;
+}
+
+struct Join {
+ 1: required JoinType type;
+ 2: required DataSource left;
+ 3: required DataSource right;
+ 4: optional Expression condition;
+}
+
+enum JoinType {
+ INNER,
+ LEFT,
+ RIGHT,
+ FULL
}
struct Expression {
@@ -52,13 +61,15 @@ struct Expression {
4: optional Identifier identifier;
}
-struct Identifier {
- 1: required string name;
+enum ExpressionType {
+ LITERAL,
+ IDENTIFIER,
+ FUNCTION
}
union Literal {
1: optional bool boolValue;
- 2: optional byte byteValue;
+ 2: optional i8 byteValue;
3: optional i16 shortValue;
4: optional i32 intValue;
5: optional i64 longValue;
@@ -69,6 +80,10 @@ union Literal {
9: optional bool nullValue;
}
+struct Identifier {
+ 1: required string name;
+}
+
struct Function {
1: required string operator;
2: optional list<Expression> operands;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]