[jira] [Commented] (DRILL-5913) DrillReduceAggregatesRule mixed the same functions of the same inputRef which have different dataTypes

2017-11-12 Thread ASF GitHub Bot (JIRA)

[ 
https://issues.apache.org/jira/browse/DRILL-5913?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16249111#comment-16249111
 ] 

ASF GitHub Bot commented on DRILL-5913:
---

Github user weijietong commented on the issue:

https://github.com/apache/drill/pull/1016
  
@amansinha100 maybe you are familiar with this part of codes .  Could you 
give a review ? anyone else will also be welcome.


> DrillReduceAggregatesRule mixed the same functions of the same inputRef which 
> have different dataTypes 
> ---
>
> Key: DRILL-5913
> URL: https://issues.apache.org/jira/browse/DRILL-5913
> Project: Apache Drill
>  Issue Type: Bug
>  Components: Query Planning & Optimization
>Affects Versions: 1.9.0, 1.11.0
>Reporter: weijie.tong
>
> sample query:
> {code:java}
> select stddev_samp(cast(employee_id as int)) as col1, sum(cast(employee_id as 
> int)) as col2 from cp.`employee.json`
> {code}
> error info:
> {code:java}
> org.apache.drill.exec.rpc.RpcException: 
> org.apache.drill.common.exceptions.UserRemoteException: SYSTEM ERROR: 
> AssertionError: Type mismatch:
> rel rowtype:
> RecordType(INTEGER $f0, INTEGER $f1, BIGINT NOT NULL $f2, INTEGER $f3) NOT 
> NULL
> equivRel rowtype:
> RecordType(INTEGER $f0, INTEGER $f1, BIGINT NOT NULL $f2, BIGINT $f3) NOT NULL
> [Error Id: f5114e62-a57b-46b1-afe8-ae652f390896 on localhost:31010]
>   (org.apache.drill.exec.work.foreman.ForemanException) Unexpected exception 
> during fragment initialization: Internal error: Error while applying rule 
> DrillReduceAggregatesRule, args 
> [rel#29:LogicalAggregate.NONE.ANY([]).[](input=rel#28:Subset#3.NONE.ANY([]).[],group={},agg#0=SUM($1),agg#1=SUM($0),agg#2=COUNT($0),agg#3=$SUM0($0))]
> org.apache.drill.exec.work.foreman.Foreman.run():294
> java.util.concurrent.ThreadPoolExecutor.runWorker():1142
> java.util.concurrent.ThreadPoolExecutor$Worker.run():617
> java.lang.Thread.run():745
>   Caused By (java.lang.AssertionError) Internal error: Error while applying 
> rule DrillReduceAggregatesRule, args 
> [rel#29:LogicalAggregate.NONE.ANY([]).[](input=rel#28:Subset#3.NONE.ANY([]).[],group={},agg#0=SUM($1),agg#1=SUM($0),agg#2=COUNT($0),agg#3=$SUM0($0))]
> org.apache.calcite.util.Util.newInternal():792
> org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch():251
> org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp():811
> {code}
> The reason is that stddev_samp(cast(employee_id as int))  will be reduced as 
> sum($0) ,sum($1) ,count($0) while the sum(cast(employee_id as int)) will be 
> reduced as sum0($0) by the DrillReduceAggregatesRule's first time matching.  
> The second time's matching will reduce stddev_samp's sum($0) to sum0($0) too 
> . But this sum0($0) 's data type is different from the first time's sum0($0) 
> : one is integer ,the other is bigint . But Calcite's addAggCall method treat 
> them as the same by ignoring their data type. This leads to the bigint 
> sum0($0) be replaced by the integer sum0($0).



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)


[jira] [Commented] (DRILL-5957) Wire protocol versioning, version negotiation

2017-11-12 Thread Paul Rogers (JIRA)

[ 
https://issues.apache.org/jira/browse/DRILL-5957?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16249084#comment-16249084
 ] 

Paul Rogers commented on DRILL-5957:


[~tdunning], good points as usual!

The end user is really the driver of version compatibility support. Drill users 
have been fairly silent on this front, so perhaps version compatibility is not 
necessary in this particular case. But, based on experience with other 
products, folks in production often need to:

* Upgrade clients and servers on slightly different schedules, forcing the need 
for older clients to talk with newer servers or visa-versa.
* If clients are installed on desktops (such as ODBC for Tableau), then the 
clients may actually be remote (or on a plane or at a customer site) at the 
time of server upgrades, forcing the need for older clients to connect to new 
servers.
* If users have multiple Drill clusters, then they may have different upgrade 
schedules, requiring that a single client be able to speak with multiple server 
versions. (In the most obvious case, a user may have version X in production, 
while trying out version (X+1) in a test environment prior to upgrade.)

Perhaps there are alternatives in the big data world. Maybe two versions of the 
Drill client can coexist in the same Tableau or other app? (For JDBC, this 
would mean that the clients must be in separate name spaces, much as SQuirreL 
does, but SQLline does not do.)

Will there be a performance hit to "transcode" vectors across versions when the 
version changes? Of course. The question is, is the temporary performance hit 
an acceptable cost to allow a staged upgrade? Or, would the users prefer to do 
an all-at-once upgrade in order to avoid the performance hit? (And, of course, 
the performance hit creates a very good incentive to upgrade...)

Finally, note that the "dbody" portion of of a Drill message exists outside of 
the Protobuf structure. A Drill message has four parts:

* Message ID
* P-body (Protobuf body) length
* P-body (Serialized Protobuf content)
* D-body (data body) length
* D-body (serialized value vectors)

For this reason, Protobuf formats don't help us with vector serialization. Note 
that vector data may be GB in size, so sending two copies is a worse 
performance impact than transcoding...

All this said, if staged upgrades and version compatibility is not a concern 
for Drill users at present, then there is no barrier to upgrading our vector 
formats; we just require new clients be used with the new Drill version. This 
would, of course, be the simplest solution by far.

> Wire protocol versioning, version negotiation
> -
>
> Key: DRILL-5957
> URL: https://issues.apache.org/jira/browse/DRILL-5957
> Project: Apache Drill
>  Issue Type: Improvement
>Affects Versions: 1.11.0
>Reporter: Paul Rogers
>
> Drill has very limited support for evolving its wire protocol. As Drill 
> becomes more widely deployed, this limitation will constrain the project's 
> ability to rapidly evolve the wire protocol based on user experience to 
> improve simplicitly, performance or minimize resource use.
> Proposed is a standard mechanism to version the API and negotiate the API 
> version between client and server at connect time. The focus here is between 
> Drill clients (JDBC, ODBC) and the Drill server. The same mechanism can also 
> be used between servers to support rolling upgrades.
> This proposal is an outline; it is not a detailed design. The purpose here is 
> to drive understanding of the problem. Once we have that, we can focus on the 
> implementation details.
> h4. Problem Statement
> The problem we wish to address here concerns both the _syntax_ and 
> _semantics_ of API messages. Syntax concerns:
> * The set of messages and their sequence
> * The format of bytes on the wire
> * The format of message packets
> Semantics concerns:
> * The meaning of each field.
> * The layout of non-message data (vectors, in Drill.)
> We wish to introduce a system whereby both syntax and semantics can be 
> evolved in a controlled, known manner such that:
> * A client of version x can connect to, and interoperate with, a server in a 
> range of versions (x-y, x+z) for some values of y and z.
> For example, version x of the Drill client is deployed in the field. It must 
> connect to the oldest Drill cluster available to that client. (That is it 
> must connect to servers up to y versions old.) During an upgrade, the server 
> may be upgraded before the client. Thus, the client must also work with 
> servers up to z versions newer than the client.
> If we wish to tackle rolling upgrades, then y and z can both be 1 for 
> server-to-server APIs. A version x server will talk with (x-1) servers when 
> the cluster upgrades to x, and will talk to (x+1) servers when the cluster is 
> 

[jira] [Commented] (DRILL-4779) Kafka storage plugin support

2017-11-12 Thread ASF GitHub Bot (JIRA)

[ 
https://issues.apache.org/jira/browse/DRILL-4779?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16249068#comment-16249068
 ] 

ASF GitHub Bot commented on DRILL-4779:
---

Github user kameshb commented on the issue:

https://github.com/apache/drill/pull/1027
  
@paul-rogers @arina-ielchiieva @vrozov 
Thanks for reviewing.  Anil & I have addressed review comments. Could you 
please go through the changes and also rest of the Kafka storage codebase.


> Kafka storage plugin support
> 
>
> Key: DRILL-4779
> URL: https://issues.apache.org/jira/browse/DRILL-4779
> Project: Apache Drill
>  Issue Type: New Feature
>  Components: Storage - Other
>Affects Versions: 1.11.0
>Reporter: B Anil Kumar
>Assignee: B Anil Kumar
>  Labels: doc-impacting
> Fix For: 1.12.0
>
>
> Implement Kafka storage plugin will enable the strong SQL support for Kafka.
> Initially implementation can target for supporting json and avro message types



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)


[jira] [Commented] (DRILL-5957) Wire protocol versioning, version negotiation

2017-11-12 Thread Ted Dunning (JIRA)

[ 
https://issues.apache.org/jira/browse/DRILL-5957?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16249063#comment-16249063
 ] 

Ted Dunning commented on DRILL-5957:



This suggestion has the virtue that only breaking changes will cause a version 
update, but it still has the problem that the version has to move no matter 
what part of the protocol changes. This is reminiscent of the old CORBA 
versioning nightmares.

Also, is there really any way to negotiate the value vector format without 
having a reformatting step inserted with fairly catastrophic performance hit?

I don't see a consideration of the cost of maintaining old version 
compatibility, either. If old client versions work, then there will be no 
incentive to upgrade. That will increase pressure to keep adding multiple 
protocol support to the server and will seemingly lock down any real progress 
just as much as client/server lockstepping. 

It seems that the short term desire here is to allow the vector format to 
change. What about making the current dvector parts be optional and adding 
alternative (optional) dvector parts in new formats? This effectively allows 
versioning of only the dvector stuff, leaving all the rest of the protocol to 
be soft-versioned as is currently done. The client advertised version could be 
used to trigger one format or the other and the incentive to upgrade is in the 
form of much slower transfer for the old format due to transcoding.





> Wire protocol versioning, version negotiation
> -
>
> Key: DRILL-5957
> URL: https://issues.apache.org/jira/browse/DRILL-5957
> Project: Apache Drill
>  Issue Type: Improvement
>Affects Versions: 1.11.0
>Reporter: Paul Rogers
>
> Drill has very limited support for evolving its wire protocol. As Drill 
> becomes more widely deployed, this limitation will constrain the project's 
> ability to rapidly evolve the wire protocol based on user experience to 
> improve simplicitly, performance or minimize resource use.
> Proposed is a standard mechanism to version the API and negotiate the API 
> version between client and server at connect time. The focus here is between 
> Drill clients (JDBC, ODBC) and the Drill server. The same mechanism can also 
> be used between servers to support rolling upgrades.
> This proposal is an outline; it is not a detailed design. The purpose here is 
> to drive understanding of the problem. Once we have that, we can focus on the 
> implementation details.
> h4. Problem Statement
> The problem we wish to address here concerns both the _syntax_ and 
> _semantics_ of API messages. Syntax concerns:
> * The set of messages and their sequence
> * The format of bytes on the wire
> * The format of message packets
> Semantics concerns:
> * The meaning of each field.
> * The layout of non-message data (vectors, in Drill.)
> We wish to introduce a system whereby both syntax and semantics can be 
> evolved in a controlled, known manner such that:
> * A client of version x can connect to, and interoperate with, a server in a 
> range of versions (x-y, x+z) for some values of y and z.
> For example, version x of the Drill client is deployed in the field. It must 
> connect to the oldest Drill cluster available to that client. (That is it 
> must connect to servers up to y versions old.) During an upgrade, the server 
> may be upgraded before the client. Thus, the client must also work with 
> servers up to z versions newer than the client.
> If we wish to tackle rolling upgrades, then y and z can both be 1 for 
> server-to-server APIs. A version x server will talk with (x-1) servers when 
> the cluster upgrades to x, and will talk to (x+1) servers when the cluster is 
> upgraded to version (x+1).
> h4. Current State
> Drill currently provides some ad-hoc version compatibility:
> * Slow change. Drill's APIs have not changed much since Drill 1.0, thereby 
> avoiding the issue.
> * Protobuf support. Drill uses Protobuf for message bodies, leveraging that 
> format's ability to absorb the additional or deprecation of individual fields.
> * API version number. The API holds a version number, though the code to use 
> it is rather ad-hoc.
> The above has allowed clever coding to handle some version changes, but each 
> is a one-off, ad-hoc collision. The recent security work is an example that, 
> with enough effort, ad-hoc solutions can be found.
> The above cannot handle:
> * Change in the message order
> * Change in the "pbody/dbody" structure of each message.
> * Change in the structure of serialized value vectors.
> As a result, the current structure prevents any change to Drill's core 
> mechanism, value vectors, as there is no way or clients and servers to 
> negotiate the vector wire format. For example, Drill cannot adopt Arrow 
> because a pre-Arrow client would not understand 

[jira] [Commented] (DRILL-4779) Kafka storage plugin support

2017-11-12 Thread ASF GitHub Bot (JIRA)

[ 
https://issues.apache.org/jira/browse/DRILL-4779?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16249039#comment-16249039
 ] 

ASF GitHub Bot commented on DRILL-4779:
---

Github user kameshb commented on a diff in the pull request:

https://github.com/apache/drill/pull/1027#discussion_r150435308
  
--- Diff: 
contrib/storage-kafka/src/main/java/org/apache/drill/exec/store/kafka/KafkaRecordReader.java
 ---
@@ -0,0 +1,178 @@
+/**
+ * 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.
+ */
+package org.apache.drill.exec.store.kafka;
+
+import static 
org.apache.drill.exec.store.kafka.DrillKafkaConfig.DRILL_KAFKA_POLL_TIMEOUT;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.drill.common.exceptions.ExecutionSetupException;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.exec.ExecConstants;
+import org.apache.drill.exec.ops.FragmentContext;
+import org.apache.drill.exec.ops.OperatorContext;
+import org.apache.drill.exec.physical.impl.OutputMutator;
+import org.apache.drill.exec.store.AbstractRecordReader;
+import org.apache.drill.exec.store.kafka.KafkaSubScan.KafkaSubScanSpec;
+import org.apache.drill.exec.store.kafka.decoders.MessageReader;
+import org.apache.drill.exec.store.kafka.decoders.MessageReaderFactory;
+import org.apache.drill.exec.util.Utilities;
+import org.apache.drill.exec.vector.complex.impl.VectorContainerWriter;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.apache.kafka.common.TopicPartition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+public class KafkaRecordReader extends AbstractRecordReader {
+  private static final Logger logger = 
LoggerFactory.getLogger(KafkaRecordReader.class);
+  public static final long DEFAULT_MESSAGES_PER_BATCH = 4000;
+
+  private VectorContainerWriter writer;
+  private MessageReader messageReader;
+
+  private boolean unionEnabled;
+  private KafkaConsumer kafkaConsumer;
+  private KafkaStoragePlugin plugin;
+  private KafkaSubScanSpec subScanSpec;
+  private long kafkaPollTimeOut;
+  private long endOffset;
+
+  private long currentOffset;
+  private long totalFetchTime = 0;
+
+  private List partitions;
+  private final boolean enableAllTextMode;
+  private final boolean readNumbersAsDouble;
+
+  private Iterator> messageIter;
+
+  public KafkaRecordReader(KafkaSubScan.KafkaSubScanSpec subScanSpec, 
List projectedColumns,
+  FragmentContext context, KafkaStoragePlugin plugin) {
+setColumns(projectedColumns);
+this.enableAllTextMode = 
context.getOptions().getOption(ExecConstants.KAFKA_ALL_TEXT_MODE).bool_val;
+this.readNumbersAsDouble = context.getOptions()
+
.getOption(ExecConstants.KAFKA_READER_READ_NUMBERS_AS_DOUBLE).bool_val;
+this.unionEnabled = 
context.getOptions().getOption(ExecConstants.ENABLE_UNION_TYPE);
+this.plugin = plugin;
+this.subScanSpec = subScanSpec;
+this.endOffset = subScanSpec.getEndOffset();
+this.kafkaPollTimeOut = 
Long.valueOf(plugin.getConfig().getDrillKafkaProps().getProperty(DRILL_KAFKA_POLL_TIMEOUT));
+  }
+
+  @Override
+  protected Collection transformColumns(Collection 
projectedColumns) {
+Set transformed = Sets.newLinkedHashSet();
+if (!isStarQuery()) {
+  for (SchemaPath column : projectedColumns) {
+transformed.add(column);
+  }
+} else {
+  transformed.add(Utilities.STAR_COLUMN);
+}

[jira] [Updated] (DRILL-5958) Revisit the List and RepeatedList vectors

2017-11-12 Thread Paul Rogers (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5958?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Rogers updated DRILL-5958:
---
Description: 
Drill provides a List vector used when reading JSON data. The semantics of this 
vector are somewhat obscure and overly complex. This ticket asks to clean up 
the design and implementation of this vector.

h4. Current Behavior

Drill contains two kinds of repeated types:

* Repeated vectors, which exist for all Drill types.
* List vectors, which exist outside the repeated vector system.

Lists are rather hard to explain.

Drill has 38 types. Each type comes in three cardinalities: Required (0), 
Optional (0, 1) or Repeated (0..n). Thus, there is an {{IntVector}}, a 
{{NullableIntVector}} and a {{RepeatedIntVector}}.

Lists are an an odd duck and exist outside of this system. A list is not simply 
another level of repetition (a {{RepeatedRepeatedIntVector}}. Rather, a list is 
heterogeneous: it is just a list of something.

A list is a semi-union: it starts as a list of something. As work progresses, 
we may realize that we need to store some other thing. At that point, the 
contents of the list morph from the original type to the union type. The result 
of this decision is that, when inspecting the metadata for a list (in the form 
of a {{MaterializedField}}), there is no information about list type. 
Presumably the code must inspect the "data vector" associated with the list to 
learn the type of the items within the list. (If done at write time, then, of 
course, the type can change as described above.)

For this reason, the List type is closely associated with the Union type: a 
list is, essentially, a "repeated Union", though it starts of as a "repeated 
something", then evolves to become a repeated union. (Drill has no 
{{RepeatedUnionVector}}, presumably because {{ListVector}} is the repeated form 
of the union type.)

Strangely, Drill also has a {{RepeatedListVector}}, which introduces all manner 
of ambiguity. Combining these, the cardinality hierarchy for unions is:

* {{UnionVector}} (like an optional union type)
* {{ListVector}} (repeated semi-union)
* {{RepeatedListVector}} (a 2D union array)
* {{RepeatedListVector}} which contains a {{ListVector}} (a 3D union grid. Note 
that this could also be implemented as a {{ListVector}} that contains a 
{{RepeatedListVector}} or even a {{ListVector}} which contains a {{ListVector}} 
which contains a {{ListVector}} which implicitly contains a {{UnionVector}}.)
* {{RepeatedListVector}} which contains a {{RepeatedListVector}} (a 4D hyper 
grid.)
* And so on.

For a primitive type, such as Int, we have:

* {{IntVector}} or {{NullableIntVector}} (cardinality of 1 or (0,1))
* {{RepeatedIntVector}} (a 1D list of Int)
* {{ListVector}} which contains a {{RepeatedIntVector}} (a 2D array of ints. 
Not that this could have been a {{RepeatedListVector}} that stores only ints.)
* {{RepeatedListVector}} which contains a {{RepeatedIntVector}} (a 3D cube of 
ints. This could also be formed by a {{ListVector}} that contains a 
{{ListVector}} that contains a {{RepeatedIntVector}} along with several other 
combinations.)

h4. Examples of Current Behavior

Lists and repeated types appeared to evolve to support JSON-like structures. 
For example:

{code}
{a: 10} {a: null}
{code}

Here, `a` is a nullable scalar and is represented as a {{NullableIntVector}}.

{code}
{a: [10, 20]}
{code}

Here, `a` is a list of Int and is represented as a {{RepeatedIntVector}}. 

Drill does not allow nulls in such vectors, so we cannot represent:

{code}
{a: [10, null, 20]}
{code}

Once we go beyond 1D, we need lists:

{code}
{a: [[10, 20], [30, 40]]}
{code}

The above requires a {{ListVector}} that contains a {{RepeatedIntVector}}.

{code}
{a: [[[110, 120], [130, 140]], [210, 220], [230, 240]]}
{code}

The above requires a {{RepeatedListVector}} that contains a 
{{RepeatedIntVector}}.

Similarly, since lists can hold any type (just like a union), we can have 
repeated objects:

{code}
{a: [[{x: 0, y: 0}, {x: 1, y: 0}], [{x: 4, y: 0}, {x: 4, y: 1}]]}
{code}

The above would be represented as a {{ListVector}} that contains a 
{{RepeatedMapVector}}. (Or, equivalently, a {{RepeatedListVector}} that 
contains a {{MapVector}}.)

Because the List vector is a union type, it can (presumably) also handle 
heterogeneous lists (though this needs to be checked to see if the code 
actually supports this case):

{code}
{a: [10, "fred", 123.45, null]}
{code}

Since unions support combinations of not just scalars, but also scalars and 
complex types, Drill can also support:

{code}
{a: [10, {b: "foo"}, null, [10, "bob"]]}
{code}

h4. Muddy Semantics

The above show a number of problems that make lists (and unions) far more 
complex than necessary:

* Ambiguity of when to use a {{ListVector}} of {{FooVector}} vs. a 
{{RepeatedFooVector}}.
* Ambiguity of when to use a {{ListVector}} of 

[jira] [Updated] (DRILL-5958) Revisit the List and RepeatedList vectors

2017-11-12 Thread Paul Rogers (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5958?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Rogers updated DRILL-5958:
---
Description: 
Drill provides a List vector used when reading JSON data. The semantics of this 
vector are somewhat obscure and overly complex. This ticket asks to clean up 
the design and implementation of this vector.

h4. Current Behavior

Drill contains two kinds of repeated types:

* Repeated vectors, which exist for all Drill types.
* List vectors, which exist outside the repeated vector system.

Lists are rather hard to explain.

Drill has 38 types. Each type comes in three cardinalities: Required (0), 
Optional (0, 1) or Repeated (0..n). Thus, there is an {{IntVector}}, a 
{{NullableIntVector}} and a {{RepeatedIntVector}}.

Lists are an an odd duck and exist outside of this system. A list is not simply 
another level of repetition (a {{RepeatedRepeatedIntVector}}. Rather, a list is 
heterogeneous: it is just a list of something.

A list is a semi-union: it starts as a list of something. As work progresses, 
we may realize that we need to store some other thing. At that point, the 
contents of the list morph from the original type to the union type. The result 
of this decision is that, when inspecting the metadata for a list (in the form 
of a {{MaterializedField}}), there is no information about list type. 
Presumably the code must inspect the "data vector" associated with the list to 
learn the type of the items within the list. (If done at write time, then, of 
course, the type can change as described above.)

For this reason, the List type is closely associated with the Union type: a 
list is, essentially, a "repeated Union", though it starts of as a "repeated 
something", then evolves to become a repeated union. (Drill has no 
{{RepeatedUnionVector}}, presumably because {{ListVector}} is the repeated form 
of the union type.)

Strangely, Drill also has a {{RepeatedListVector}}, which introduces all manner 
of ambiguity. Combining these, the cardinality hierarchy for unions is:

* {{UnionVector}} (like an optional union type)
* {{ListVector}} (repeated semi-union)
* {{RepeatedListVector}} (a 2D union array)
* {{RepeatedListVector}} which contains a {{ListVector}} (a 3D union grid. Note 
that this could also be implemented as a {{ListVector}} that contains a 
{{RepeatedListVector}}.)
* {{RepeatedListVector}} which contains a {{RepeatedListVector}} (a 4D hyper 
grid.)
* And so on.

For a primitive type, such as Int, we have:

* {{IntVector}} or {{NullableIntVector}} (cardinality of 1 or (0,1))
* {{RepeatedIntVector}} (a 1D list of Int)
* {{ListVector}} which contains a {{RepeatedIntVector}} (a 2D array of ints. 
Not that this could have been a {{RepeatedListVector}} that stores only ints.)
* {{RepeatedListVector}} which contains a {{RepeatedIntVector}} (a 3D cube of 
ints. This could also be formed by a {{ListVector}} that contains a 
{{ListVector}} that contains a {{RepeatedIntVector}} along with several other 
combinations.)

h4. Examples of Current Behavior

Lists and repeated types appeared to evolve to support JSON-like structures. 
For example:

{code}
{a: 10} {a: null}
{code}

Here, `a` is a nullable scalar and is represented as a {{NullableIntVector}}.

{code}
{a: [10, 20]}
{code}

Here, `a` is a list of Int and is represented as a {{RepeatedIntVector}}. 

Drill does not allow nulls in such vectors, so we cannot represent:

{code}
{a: [10, null, 20]}
{code}

Once we go beyond 1D, we need lists:

{code}
{a: [[10, 20], [30, 40]]}
{code}

The above requires a {{ListVector}} that contains a {{RepeatedIntVector}}.

{code}
{a: [[[110, 120], [130, 140]], [210, 220], [230, 240]]}
{code}

The above requires a {{RepeatedListVector}} that contains a 
{{RepeatedIntVector}}.

Similarly, since lists can hold any type (just like a union), we can have 
repeated objects:

{code}
{a: [[{x: 0, y: 0}, {x: 1, y: 0}], [{x: 4, y: 0}, {x: 4, y: 1}]]}
{code}

The above would be represented as a {{ListVector}} that contains a 
{{RepeatedMapVector}}. (Or, equivalently, a {{RepeatedListVector}} that 
contains a {{MapVector}}.)

Because the List vector is a union type, it can (presumably) also handle 
heterogeneous lists (though this needs to be checked to see if the code 
actually supports this case):

{code}
{a: [10, "fred", 123.45, null]}
{code}

Since unions support combinations of not just scalars, but also scalars and 
complex types, Drill can also support:

{code}
{a: [10, {b: "foo"}, null, [10, "bob"]]}
{code}

h4. Muddy Semantics

The above show a number of problems that make lists (and unions) far more 
complex than necessary:

* Ambiguity of when to use a {{ListVector}} of {{FooVector}} vs. a 
{{RepeatedFooVector}}.
* Ambiguity of when to use a {{ListVector}} of {{RepeatedFooVector}} vs. a 
{{RepeatedListVector}} of {{FooVector}}.

The same solution used to handle extra layers of repetition is used to handle 

[jira] [Updated] (DRILL-5955) Revisit Union Vectors

2017-11-12 Thread Paul Rogers (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5955?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Rogers updated DRILL-5955:
---
Description: 
Drill supports a “Union Vector” type that allows a single column to hold values 
of multiple types. Conceptually, each column value is a (type, value) pair. For 
example, row 0 might be an Int, row 1 a Varchar and row 2 a NULL value.

The name refers to a C “union” in which the same bit of memory is used to 
represent one of a set of defined types.

Drill implements the union vector a bit like a map: as a collection of typed 
vectors. Each value is keyed by type. The result is that a union vector is more 
like a C “struct” than a C “union”: every vector takes space, but only one of 
the vectors is used for each row. For the example above, the union vector 
contains an Int vector, a Varchar vector and a type vector. For each row, 
either the Int or the Varchar is used. For NULL values, neither vector is used.

h4. Memory Footprint Concerns

The current representation, despite its name, makes very inefficient use of 
memory because it requires the sum of the storage for each included type. (That 
is, if we store 1000 rows, we need 1000 slots for integers, another 1000 for 
Varchar and yet another 1000 for the type vector.)

Drill poorly supports the union type. One operator that does support it is the 
sort. If the union type is enabled, and the sort sees a schema change, the sort 
will create a new union vector that combines the two types. The result is a 
sudden, unplanned increase in memory usage. Since the sort can buffer many 
hundreds of batches, this unplanned memory increase can cause the sort to run 
out of memory.

h4. Muddy Semantics

The union vector is closely tied with the List vector: a list vector is, 
essentially, an array of unions. (See DRILL-5958). The list type is used to 
model JSON in which a list can hold anything: another list, an object or 
scalars. For this reason, the union vector also can hold any type. And, indeed, 
it can hold a union of any of these types: a Map and an Int, or a List and a 
Map.

Drill is a relational, SQL-based tool. Work is required to bring non-relational 
structures into Drill. As discussed below, a union of scalars can be made to 
work. But, a union of structured types (lists, arrays or Maps) makes no sense.

h4. High Complexity

The union vector, as implemented is quite complex. It contains member variables 
for every other vector type (except, strangely, the decimal types.) Access to 
typed members is by type-specific methods, meaning that the client code must 
include a separate call for every type, resulting in very complex client code.

The complexity allowed the union type to be made to work, but causes this one 
type to consume a disproportionate amount of the vector and client code.

h4. Proposed Revision to Structure: The Variant Type

Given the above, we can now present the proposed changes. First let us 
recognize that a union vector need not hold structured types; there are other 
solutions as discussed in DRILL-. This leaves the union vector to hold just 
scalars.

h4. Proposed Revision to Storage

This in turn lets us adopt the [Variant 
type|https://en.wikipedia.org/wiki/Variant_type] originally introduced in 
Visual Basic. Variant “is a tagged union that can be used to represent any 
other data type”. The Variant type was designed to be compact by building on 
the idea of a tagged union in C.

{code}
struct {
  int tag; // type
  union {
int intValue;
long longValue;
…
  }
}
{code}

When implemented as a vector, the format could consume just a single 
variable-width vector with each entry of the form: {{\[type value]}}. The 
vector is simply a sequence of these (type, value) pairs.

The type is a single-byte that encodes the MinorType that describes the value. 
That is, the type byte is like the existing type vector, but stored in the same 
location as the data. The data is simply the serialized format of data. (Four 
bytes for an Int, 8 bytes for a Float8 and so on.)

Variable-width types require an extra field: the type field: {{\[type length 
value]}}. For example, a Varchar would be encoded as {{\[Varchar 27 byte0-26]}}.

A writer uses the type to drive the serialization. A reader uses the type to 
drive deserialization.

Note that the type field must include a special marker for nulls. Today, the 
union type uses 0 to indicate a null value. (Note that, in a union and variant, 
a null value is not a null of some type, both the type and value are null.) 
That form should be used in the variant representation as well. But, note that 
the 0 value in the MajorType enum is not Null but is instead Late. This is an 
unpleasant messiness that the union (and variant )encoding must handle.

An offset vector provides the location of each field, as is done with 
variable-length vectors today.

The result is huge compaction 

[jira] [Created] (DRILL-5958) Revisit the List and RepeatedList vectors

2017-11-12 Thread Paul Rogers (JIRA)
Paul Rogers created DRILL-5958:
--

 Summary: Revisit the List and RepeatedList vectors
 Key: DRILL-5958
 URL: https://issues.apache.org/jira/browse/DRILL-5958
 Project: Apache Drill
  Issue Type: Improvement
Affects Versions: 1.11.0
Reporter: Paul Rogers


Drill provides a List vector used when reading JSON data. The semantics of this 
vector are somewhat obscure and overly complex. This ticket asks to clean up 
the design and implementation of this vector.

h4. Current Behavior

Drill contains two kinds of repeated types:

* Repeated vectors, which exist for all Drill types.
* List vectors, which exist outside the repeated vector system.

Lists are rather hard to explain.

Drill has 38 types. Each type comes in three cardinalities: Required (0), 
Optional (0, 1) or Repeated (0..n). Thus, there is an {{IntVector}}, a 
{{NullableIntVector}} and a {{RepeatedIntVector}}.

Lists are an an odd duck and exist outside of this system. A list is not simply 
another level of repetition (a {{RepeatedRepeatedIntVector}}. Rather, a list is 
heterogeneous: it is just a list of something.

For this reason, the List type is closely associated with the Union type: a 
list is, essentially, a "repeated Union", though it is not implemented that way.

Strangely, Drill does have a {{RepeatedListVector}}, which introduces all 
manner of ambiguity. Combining these, the cardinality hierarchy for unions is:

* {{UnionVector}} (like an optional union type)
* {{ListVector}} (repeated union)
* {{RepeatedListVector}} (a 2D union array)
* {{RepeatedListVector}} which contains a {{ListVector}} (a 3D union grid. Note 
that this could also be implemented as a {{ListVector}} that contains a 
{{RepeatedListVector}}.)
* {{RepeatedListVector}} which contains a {{RepeatedListVector}} (a 4D hyper 
grid.)
* And so on.

For a primitive type, such as Int, we have:

* {{IntVector}} or {{NullableIntVector}} (cardinality of 1 or (0,1))
* {{RepeatedIntVector}} (a 1D list of Int)
* {{ListVector}} which contains a {{RepeatedIntVector}} (a 2D array of ints. 
Not that this could have been a {{RepeatedListVector}} that stores only ints.)
* {{RepeatedListVector}} which contains a {{RepeatedIntVector}} (a 3D cube of 
ints. This could also be formed by a {{ListVector}} that contains a 
{{ListVector}} that contains a {{RepeatedIntVector}} along with several other 
combinations.)

h4. Examples of Current Behavior

Lists and repeated types appeared to evolve to support JSON-like structures. 
For example:

{code}
{a: 10} {a: null}
{code}

Here, `a` is a nullable scalar and is represented as a {{NullableIntVector}}.

{code}
{a: [10, 20]}
{code}

Here, `a` is a list of Int and is represented as a {{RepeatedIntVector}}. 

Drill does not allow nulls in such vectors, so we cannot represent:

{code}
{a: [10, null, 20]}
{code}

Once we go beyond 1D, we need lists:

{code}
{a: [[10, 20], [30, 40]]}
{code}

The above requires a {{ListVector}} that contains a {{RepeatedIntVector}}.

{code}
{a: [[[110, 120], [130, 140]], [210, 220], [230, 240]]}
{code}

The above requires a {{RepeatedListVector}} that contains a 
{{RepeatedIntVector}}.

Similarly, since lists can hold any type (just like a union), we can have 
repeated objects:

{code}
{a: [[{x: 0, y: 0}, {x: 1, y: 0}], [{x: 4, y: 0}, {x: 4, y: 1}]]}
{code}

The above would be represented as a {{ListVector}} that contains a 
{{RepeatedMapVector}}. (Or, equivalently, a {{RepeatedListVector}} that 
contains a {{MapVector}}.)

Because the List vector is a union type, it can (presumably) also handle 
heterogeneous lists (though this needs to be checked to see if the code 
actually supports this case):

{code}
{a: [10, "fred", 123.45, null]}
{code}

Since unions support combinations of not just scalars, but also scalars and 
complex types, Drill can also support:

{code}
{a: [10, {b: "foo"}, null, [10, "bob"]]}
{code}

h4. Muddy Semantics

The above show a number of problems that make lists (and unions) far more 
complex than necessary:

* Ambiguity of when to use a {{ListVector}} of {{FooVector}} vs. a 
{{RepeatedFooVector}}.
* Ambiguity of when to use a {{ListVector}} of {{RepeatedFooVector}} vs. a 
{{RepeatedListVector}} of {{FooVector}}.

The same solution used to handle extra layers of repetition is used to handle 
variant types (DRILL-5955):

* Lists can handle any combination of scalars.
* Lists can handle any structure type (map, repeated map, list, repeated list).
* Lists are thus not typed. They are not a "List of Int", they are just a List.

h4. Mapping to SQL

The above muddy semantics give rise to this question. Drill is a SQL engine, 
how do we map the List semantics to a relational schema? If we don't have a 
clean answer, then the List type, while clever, does not have a useful purpose 
and is instead distracting us from the larger question of how we map JSON-like 
structures to a relational schema.


[jira] [Updated] (DRILL-5955) Revisit Union Vectors

2017-11-12 Thread Paul Rogers (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5955?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Rogers updated DRILL-5955:
---
Description: 
Drill supports a “Union Vector” type that allows a single column to hold values 
of multiple types. Conceptually, each column value is a (type, value) pair. For 
example, row 0 might be an Int, row 1 a Varchar and row 2 a NULL value.

The name refers to a C “union” in which the same bit of memory is used to 
represent one of a set of defined types.

Drill implements the union vector a bit like a map: as a collection of typed 
vectors. Each value is keyed by type. The result is that a union vector is more 
like a C “struct” than a C “union”: every vector takes space, but only one of 
the vectors is used for each row. For the example above, the union vector 
contains an Int vector, a Varchar vector and a type vector. For each row, 
either the Int or the Varchar is used. For NULL values, neither vector is used.

h4. Memory Footprint Concerns

The current representation, despite its name, makes very inefficient use of 
memory because it requires the sum of the storage for each included type. (That 
is, if we store 1000 rows, we need 1000 slots for integers, another 1000 for 
Varchar and yet another 1000 for the type vector.)

Drill poorly supports the union type. One operator that does support it is the 
sort. If the union type is enabled, and the sort sees a schema change, the sort 
will create a new union vector that combines the two types. The result is a 
sudden, unplanned increase in memory usage. Since the sort can buffer many 
hundreds of batches, this unplanned memory increase can cause the sort to run 
out of memory.

h4. Muddy Semantics

The union vector is closely tied with the List vector: a list vector is, 
essentially, an array of unions. (See DRILL-). The list type is used to 
model JSON in which a list can hold anything: another list, an object or 
scalars. For this reason, the union vector also can hold any type. And, indeed, 
it can hold a union of any of these types: a Map and an Int, or a List and a 
Map.

Drill is a relational, SQL-based tool. Work is required to bring non-relational 
structures into Drill. As discussed below, a union of scalars can be made to 
work. But, a union of structured types (lists, arrays or Maps) makes no sense.

h4. High Complexity

The union vector, as implemented is quite complex. It contains member variables 
for every other vector type (except, strangely, the decimal types.) Access to 
typed members is by type-specific methods, meaning that the client code must 
include a separate call for every type, resulting in very complex client code.

The complexity allowed the union type to be made to work, but causes this one 
type to consume a disproportionate amount of the vector and client code.

h4. Proposed Revision to Structure: The Variant Type

Given the above, we can now present the proposed changes. First let us 
recognize that a union vector need not hold structured types; there are other 
solutions as discussed in DRILL-. This leaves the union vector to hold just 
scalars.

h4. Proposed Revision to Storage

This in turn lets us adopt the [Variant 
type|https://en.wikipedia.org/wiki/Variant_type] originally introduced in 
Visual Basic. Variant “is a tagged union that can be used to represent any 
other data type”. The Variant type was designed to be compact by building on 
the idea of a tagged union in C.

{code}
struct {
  int tag; // type
  union {
int intValue;
long longValue;
…
  }
}
{code}

When implemented as a vector, the format could consume just a single 
variable-width vector with each entry of the form: {{\[type value]}}. The 
vector is simply a sequence of these (type, value) pairs.

The type is a single-byte that encodes the MinorType that describes the value. 
That is, the type byte is like the existing type vector, but stored in the same 
location as the data. The data is simply the serialized format of data. (Four 
bytes for an Int, 8 bytes for a Float8 and so on.)

Variable-width types require an extra field: the type field: {{\[type length 
value]}}. For example, a Varchar would be encoded as {{\[Varchar 27 byte0-26]}}.

A writer uses the type to drive the serialization. A reader uses the type to 
drive deserialization.

Note that the type field must include a special marker for nulls. Today, the 
union type uses 0 to indicate a null value. (Note that, in a union and variant, 
a null value is not a null of some type, both the type and value are null.) 
That form should be used in the variant representation as well. But, note that 
the 0 value in the MajorType enum is not Null but is instead Late. This is an 
unpleasant messiness that the union (and variant )encoding must handle.

An offset vector provides the location of each field, as is done with 
variable-length vectors today.

The result is huge compaction 

[jira] [Updated] (DRILL-5957) Wire protocol versioning, version negotiation

2017-11-12 Thread Paul Rogers (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5957?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Rogers updated DRILL-5957:
---
Description: 
Drill has very limited support for evolving its wire protocol. As Drill becomes 
more widely deployed, this limitation will constrain the project's ability to 
rapidly evolve the wire protocol based on user experience to improve 
simplicitly, performance or minimize resource use.

Proposed is a standard mechanism to version the API and negotiate the API 
version between client and server at connect time. The focus here is between 
Drill clients (JDBC, ODBC) and the Drill server. The same mechanism can also be 
used between servers to support rolling upgrades.

This proposal is an outline; it is not a detailed design. The purpose here is 
to drive understanding of the problem. Once we have that, we can focus on the 
implementation details.

h4. Problem Statement

The problem we wish to address here concerns both the _syntax_ and _semantics_ 
of API messages. Syntax concerns:

* The set of messages and their sequence
* The format of bytes on the wire
* The format of message packets

Semantics concerns:

* The meaning of each field.
* The layout of non-message data (vectors, in Drill.)

We wish to introduce a system whereby both syntax and semantics can be evolved 
in a controlled, known manner such that:

* A client of version x can connect to, and interoperate with, a server in a 
range of versions (x-y, x+z) for some values of y and z.

For example, version x of the Drill client is deployed in the field. It must 
connect to the oldest Drill cluster available to that client. (That is it must 
connect to servers up to y versions old.) During an upgrade, the server may be 
upgraded before the client. Thus, the client must also work with servers up to 
z versions newer than the client.

If we wish to tackle rolling upgrades, then y and z can both be 1 for 
server-to-server APIs. A version x server will talk with (x-1) servers when the 
cluster upgrades to x, and will talk to (x+1) servers when the cluster is 
upgraded to version (x+1).

h4. Current State

Drill currently provides some ad-hoc version compatibility:

* Slow change. Drill's APIs have not changed much since Drill 1.0, thereby 
avoiding the issue.
* Protobuf support. Drill uses Protobuf for message bodies, leveraging that 
format's ability to absorb the additional or deprecation of individual fields.
* API version number. The API holds a version number, though the code to use it 
is rather ad-hoc.

The above has allowed clever coding to handle some version changes, but each is 
a one-off, ad-hoc collision. The recent security work is an example that, with 
enough effort, ad-hoc solutions can be found.

The above cannot handle:

* Change in the message order
* Change in the "pbody/dbody" structure of each message.
* Change in the structure of serialized value vectors.

As a result, the current structure prevents any change to Drill's core 
mechanism, value vectors, as there is no way or clients and servers to 
negotiate the vector wire format. For example, Drill cannot adopt Arrow because 
a pre-Arrow client would not understand "dbody" message parts encoded in Arrow 
format and visa-versa.

h4. API Version

The core of the proposal is to introduce an API version. This is a simple 
integer which is incremented each time that a breaking change is made to the 
API. (If the change can be absorbed by the Protobuf mechanism, then it is not a 
breaking change.) Note that the API version *is not* the same as the product 
version. Two different Drill versions may have the same API version if nothing 
changed in the API.

h4. Version Negotiation

Given a set of well-defined protocol versions, we can next define the version 
negotiation protocol between client and server:

* The client connects and sends a "hello" message that identifies the range of 
API versions that it supports, with the newest version being the version of the 
client itself.
* The server receives the message and computes the version of the session as 
the newest client version the the server supports.
* The server returns this version to the client which switches to the selected 
API version. (The server returns an error, and disconnects, if there is no 
common version.)
* The server and client use only messages valid for the given API version. This 
may mean converting data from one representation to another.

The above is pretty standard.

h4. Backward Compatibility Implementation

Consider a server that must work with its own version (version c) and, say, two 
older versions (a and b).

In most cases, changes across versions are minor. Perhaps version b introduced 
a better error reporting format (akin to SQLWARN and SQLERROR codes). Version c 
may have change the layout of a particular vector (or introduce a new vector 
type.) How does the server handle these when talking with 

[jira] [Created] (DRILL-5957) Wire protocol versioning, version negotiation

2017-11-12 Thread Paul Rogers (JIRA)
Paul Rogers created DRILL-5957:
--

 Summary: Wire protocol versioning, version negotiation
 Key: DRILL-5957
 URL: https://issues.apache.org/jira/browse/DRILL-5957
 Project: Apache Drill
  Issue Type: Improvement
Affects Versions: 1.11.0
Reporter: Paul Rogers


Drill has very limited support for evolving its wire protocol. As Drill becomes 
more widely deployed, this limitation will constrain the project's ability to 
rapidly evolve the wire protocol based on user experience to improve 
simplicitly, performance or minimize resource use.

Proposed is a standard mechanism to version the API and negotiate the API 
version between client and server at connect time. The focus here is between 
Drill clients (JDBC, ODBC) and the Drill server. The same mechanism can also be 
used between servers to support rolling upgrades.

This proposal is an outline; it is not a detailed design. The purpose here is 
to drive understanding of the problem. Once we have that, we can focus on the 
implementation details.

h4. Problem Statement

The problem we wish to address here concerns both the _syntax_ and _semantics_ 
of API messages. Syntax concerns:

* The set of messages and their sequence
* The format of bytes on the wire
* The format of message packets

Semantics concerns:

* The meaning of each field.
* The layout of non-message data (vectors, in Drill.)

We wish to introduce a system whereby both syntax and semantics can be evolved 
in a controlled, known manner such that:

* A client of version x can connect to, and interoperate with, a server in a 
range of versions (x-y, x+z) for some values of y and z.

For example, version x of the Drill client is deployed in the field. It must 
connect to the oldest Drill cluster available to that client. (That is it must 
connect to servers up to y versions old.) During an upgrade, the server may be 
upgraded before the client. Thus, the client must also work with servers up to 
z versions newer than the client.

If we wish to tackle rolling upgrades, then y and z can both be 1 for 
server-to-server APIs. A version x server will talk with (x-1) servers when the 
cluster upgrades to x, and will talk to (x+1) servers when the cluster is 
upgraded to version (x+1).

h4. Current State

Drill currently provides some ad-hoc version compatibility:

* Slow change. Drill's APIs have not changed much since Drill 1.0, thereby 
avoiding the issue.
* Protobuf support. Drill uses Protobuf for message bodies, leveraging that 
format's ability to absorb the additional or deprecation of individual fields.
* API version number. The API holds a version number, though the code to use it 
is rather ad-hoc.

The above has allowed clever coding to handle some version changes, but each is 
a one-off, ad-hoc collision. The recent security work is an example that, with 
enough effort, ad-hoc solutions can be found.

The above cannot handle:

* Change in the message order
* Change in the "pbody/dbody" structure of each message.
* Change in the structure of serialized value vectors.

As a result, the current structure prevents any change to Drill's core 
mechanism, value vectors, as there is no way or clients and servers to 
negotiate the vector wire format. For example, Drill cannot adopt Arrow because 
a pre-Arrow client would not understand "dbody" message parts encoded in Arrow 
format and visa-versa.

h4. API Version

The core of the proposal is to introduce an API version. This is a simple 
integer which is incremented each time that a breaking change is made to the 
API. (If the change can be absorbed by the Protobuf mechanism, then it is not a 
breaking change.) Note that the API version *is not* the same as the product 
version. Two different Drill versions may have the same API version if nothing 
changed in the API.

h4. Version Negotiation

Given a set of well-defined protocol versions, we can next define the version 
negotiation protocol between client and server:

* The client connects and sends a "hello" message that identifies the range of 
API versions that it supports, with the newest version being the version of the 
client itself.
* The server receives the message and computes the version of the session as 
the newest client version the the server supports.
* The server returns this version to the client which switches to the selected 
API version. (The server returns an error, and disconnects, if there is no 
common version.)
* The server and client use only messages valid for the given API version. This 
may mean converting data from one representation to another.

The above is pretty standard.

h4. Backward Compatibility Implementation

Consider a server that must work with its own version (version c) and, say, two 
older versions (a and b).

In most cases, changes across versions are minor. Perhaps version b introduced 
a better error reporting format (akin to SQLWARN and 

[jira] [Updated] (DRILL-5956) Add storage plugin for Druid

2017-11-12 Thread Jiaqi Liu (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5956?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jiaqi Liu updated DRILL-5956:
-
Component/s: Storage - Other

> Add storage plugin for Druid
> 
>
> Key: DRILL-5956
> URL: https://issues.apache.org/jira/browse/DRILL-5956
> Project: Apache Drill
>  Issue Type: Wish
>  Components: Storage - Other
>Reporter: Jiaqi Liu
>
> As more and more companies are using Druid for mission-critical industrial 
> products, Drill could gain much more popularity with Druid as one of its 
> supported storage plugin so that uses could easily bind Druid cluster to 
> running Drill instance



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)


[jira] [Created] (DRILL-5956) Add storage plugin for Druid

2017-11-12 Thread Jiaqi Liu (JIRA)
Jiaqi Liu created DRILL-5956:


 Summary: Add storage plugin for Druid
 Key: DRILL-5956
 URL: https://issues.apache.org/jira/browse/DRILL-5956
 Project: Apache Drill
  Issue Type: Wish
Reporter: Jiaqi Liu


As more and more companies are using Druid for mission-critical industrial 
products, Drill could gain much more popularity with Druid as one of its 
supported storage plugin so that uses could easily bind Druid cluster to 
running Drill instance



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)


[jira] [Updated] (DRILL-5955) Revisit Union Vectors

2017-11-12 Thread Paul Rogers (JIRA)

 [ 
https://issues.apache.org/jira/browse/DRILL-5955?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Rogers updated DRILL-5955:
---
Description: 
Drill supports a “Union Vector” type that allows a single column to hold values 
of multiple types. Conceptually, each column value is a (type, value) pair. For 
example, row 0 might be an Int, row 1 a Varchar and row 2 a NULL value.

The name refers to a C “union” in which the same bit of memory is used to 
represent one of a set of defined types.

Drill implements the union vector a bit like a map: as a collection of typed 
vectors. Each value is keyed by type. The result is that a union vector is more 
like a C “struct” than a C “union”: every vector takes space, but only one of 
the vectors is used for each row. For the example above, the union vector 
contains an Int vector, a Varchar vector and a type vector. For each row, 
either the Int or the Varchar is used. For NULL values, neither vector is used.

h4. Memory Footprint Concerns

The current representation, despite its name, makes very inefficient use of 
memory because it requires the sum of the storage for each included type. (That 
is, if we store 1000 rows, we need 1000 slots for integers, another 1000 for 
Varchar and yet another 1000 for the type vector.)

Drill poorly supports the union type. One operator that does support it is the 
sort. If the union type is enabled, and the sort sees a schema change, the sort 
will create a new union vector that combines the two types. The result is a 
sudden, unplanned increase in memory usage. Since the sort can buffer many 
hundreds of batches, this unplanned memory increase can cause the sort to run 
out of memory.

h4. Muddy Semantics

The union vector is closely tied with the List vector: a list vector is, 
essentially, an array of unions. (See DRILL-). The list type is used to 
model JSON in which a list can hold anything: another list, an object or 
scalars. For this reason, the union vector also can hold any type. And, indeed, 
it can hold a union of any of these types: a Map and an Int, or a List and a 
Map.

Drill is a relational, SQL-based tool. Work is required to bring non-relational 
structures into Drill. As discussed below, a union of scalars can be made to 
work. But, a union of structured types (lists, arrays or Maps) makes no sense.

h4. High Complexity

The union vector, as implemented is quite complex. It contains member variables 
for every other vector type (except, strangely, the decimal types.) Access to 
typed members is by type-specific methods, meaning that the client code must 
include a separate call for every type, resulting in very complex client code.

The complexity allowed the union type to be made to work, but causes this one 
type to consume a disproportionate amount of the vector and client code.

h4. Proposed Revision to Structure: The Variant Type

Given the above, we can now present the proposed changes. First let us 
recognize that a union vector need not hold structured types; there are other 
solutions as discussed in DRILL-. This leaves the union vector to hold just 
scalars.

h4. Proposed Revision to Storage

This in turn lets us adopt the [Variant 
type|https://en.wikipedia.org/wiki/Variant_type] originally introduced in 
Visual Basic. Variant “is a tagged union that can be used to represent any 
other data type”. The Variant type was designed to be compact by building on 
the idea of a tagged union in C.

{code}
struct {
  int tag; // type
  union {
int intValue;
long longValue;
…
  }
}
{code}

When implemented as a vector, the format could consume just a single 
variable-width vector with each entry of the form: {{\[type value]}}. The 
vector is simply a sequence of these (type, value) pairs.

The type is a single-byte that encodes the MinorType that describes the value. 
That is, the type byte is like the existing type vector, but stored in the same 
location as the data. The data is simply the serialized format of data. (Four 
bytes for an Int, 8 bytes for a Float8 and so on.)

Variable-width types require an extra field: the type field: {{\[type length 
value]}}. For example, a Varchar would be encoded as {{\[Varchar 27 byte0-26]}}.

A writer uses the type to drive the serialization. A reader uses the type to 
drive deserialization.

Note that the type field must include a special marker for nulls. Today, the 
union type uses 0 to indicate a null value. (Note that, in a union and variant, 
a null value is not a null of some type, both the type and value are null.) 
That form should be used in the variant representation as well. But, note that 
the 0 value in the MajorType enum is not Null but is instead Late. This is an 
unpleasant messiness that the union (and variant )encoding must handle.

An offset vector provides the location of each field, as is done with 
variable-length vectors today.

The result is huge compaction 

[jira] [Commented] (DRILL-4092) Support for INTERSECT

2017-11-12 Thread Khurram Faraaz (JIRA)

[ 
https://issues.apache.org/jira/browse/DRILL-4092?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16248982#comment-16248982
 ] 

Khurram Faraaz commented on DRILL-4092:
---

[~prasadns14]

{noformat}
Here are some links to INTERSECT set operator in existing DBMSs

(1) 
https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_1834.htm

(2) https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries004.htm

(3) https://www.postgresql.org/docs/9.6/static/sql-select.html
{noformat}

> Support for INTERSECT 
> --
>
> Key: DRILL-4092
> URL: https://issues.apache.org/jira/browse/DRILL-4092
> Project: Apache Drill
>  Issue Type: New Feature
>Reporter: Victoria Markman
>Assignee: Prasad Nagaraj Subramanya
>




--
This message was sent by Atlassian JIRA
(v6.4.14#64029)


[jira] [Created] (DRILL-5955) Revisit Union Vectors

2017-11-12 Thread Paul Rogers (JIRA)
Paul Rogers created DRILL-5955:
--

 Summary: Revisit Union Vectors
 Key: DRILL-5955
 URL: https://issues.apache.org/jira/browse/DRILL-5955
 Project: Apache Drill
  Issue Type: Improvement
Affects Versions: 1.11.0
Reporter: Paul Rogers


Drill supports a “Union Vector” type that allows a single column to hold values 
of multiple types. Conceptually, each column value is a (type, value) pair. For 
example, row 0 might be an Int, row 1 a Varchar and row 2 a NULL value.

The name refers to a C “union” in which the same bit of memory is used to 
represent one of a set of defined types.

Drill implements the union vector a bit like a map: as a collection of typed 
vectors. Each value is keyed by type. The result is that a union vector is more 
like a C “struct” than a C “union”: every vector takes space, but only one of 
the vectors is used for each row. For the example above, the union vector 
contains an Int vector, a Varchar vector and a type vector. For each row, 
either the Int or the Varchar is used. For NULL values, neither vector is used.

h4. Memory Footprint Concerns

The current representation, despite its name, makes very inefficient use of 
memory because it requires the sum of the storage for each included type. (That 
is, if we store 1000 rows, we need 1000 slots for integers, another 1000 for 
Varchar and yet another 1000 for the type vector.)

Drill poorly supports the union type. One operator that does support it is the 
sort. If the union type is enabled, and the sort sees a schema change, the sort 
will create a new union vector that combines the two types. The result is a 
sudden, unplanned increase in memory usage. Since the sort can buffer many 
hundreds of batches, this unplanned memory increase can cause the sort to run 
out of memory.

h4. Muddy Semantics

The union vector is closely tied with the List vector: a list vector is, 
essentially, an array of unions. (See DRILL-). The list type is used to 
model JSON in which a list can hold anything: another list, an object or 
scalars. For this reason, the union vector also can hold any type. And, indeed, 
it can hold a union of any of these types: a Map and an Int, or a List and a 
Map.

Drill is a relational, SQL-based tool. Work is required to bring non-relational 
structures into Drill. As discussed below, a union of scalars can be made to 
work. But, a union of structured types (lists, arrays or Maps) makes no sense.

h4. High Complexity

The union vector, as implemented is quite complex. It contains member variables 
for every other vector type (except, strangely, the decimal types.) Access to 
typed members is by type-specific methods, meaning that the client code must 
include a separate call for every type, resulting in very complex client code.

The complexity allowed the union type to be made to work, but causes this one 
type to consume a disproportionate amount of the vector and client code.

h4. Proposed Revision to Structure: The Variant Type

Given the above, we can now present the proposed changes. First let us 
recognize that a union vector need not hold structured types; there are other 
solutions as discussed in DRILL-. This leaves the union vector to hold just 
scalars.

h4. Proposed Revision to Storage

This in turn lets us adopt the [Variant 
type|https://en.wikipedia.org/wiki/Variant_type] originally introduced in 
Visual Basic. Variant “is a tagged union that can be used to represent any 
other data type”. The Variant type was designed to be compact by building on 
the idea of a tagged union in C.

{code}
struct {
  int tag; // type
  union {
int intValue;
long longValue;
…
  }
}
{code}

When implemented as a vector, the format could consume just a single 
variable-width vector with each entry of the form: {{\[type value]}}. The 
vector is simply a sequence of these (type, value) pairs.

The type is a single-byte that encodes the MinorType that describes the value. 
That is, the type byte is like the existing type vector, but stored in the same 
location as the data. The data is simply the serialized format of data. (Four 
bytes for an Int, 8 bytes for a Float8 and so on.)

Variable-width types require an extra field: the type field: {{\[type length 
value]}}. For example, a Varchar would be encoded as {{\[Varchar 27 byte0-26]}}.

A writer uses the type to drive the serialization. A reader uses the type to 
drive deserialization.

Note that the type field must include a special marker for nulls. Today, the 
union type uses 0 to indicate a null value. (Note that, in a union and variant, 
a null value is not a null of some type, both the type and value are null.) 
That form should be used in the variant representation as well. But, note that 
the 0 value in the MajorType enum is not Null but is instead Late. This is an 
unpleasant messiness that the union (and variant )encoding must