[ https://issues.apache.org/jira/browse/DRILL-5419?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15987999#comment-15987999 ]
ASF GitHub Bot commented on DRILL-5419: --------------------------------------- Github user paul-rogers commented on a diff in the pull request: https://github.com/apache/drill/pull/819#discussion_r113835436 --- Diff: exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillConcatFuncHolder.java --- @@ -0,0 +1,62 @@ +/* + * 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.expr.fn; + +import org.apache.drill.common.expression.LogicalExpression; +import org.apache.drill.common.types.TypeProtos; +import org.apache.drill.common.types.Types; + +import java.util.List; + +/** + * Function holder for functions with function scope set as + * {@link org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope#CONCAT}. + */ +public class DrillConcatFuncHolder extends DrillSimpleFuncHolder { --- End diff -- As Jinfeng noted, we are extending a concept meant for one purpose and using it for another. We may not be stretching it to the breaking point yet, but I can see that coming. What we really have is the idea of a function definition (what we call a "holder.") That definition has many aspects: signature, type inference, etc. We are using a single class with all properties and using inheritance to share properties. (Here, we are using inheritance for any concat-style function.) But, what happens for a function that acts like concat in one area, but like something else in another? We have to copy & paste code to create a mixture class. Better would be to hold each property as a separate class. That is, decorate the function definition with its types, with its cast rules, with its type inference rules, and so on, each expressed as a class. By this: ``` public interface TypeInference { MajorType returnType(); } public interface CastInference { Something inferCast(); } Then, create instances that implement each rule set. Finally, create function rules that are collection of property rules: FunctionDefn = new FunctionDefnBuilder() .returnType( concatReturnType ) .cast( somethingCastRules ) .name( "org.apache.drill.some.package.MyFunc" ) .build(); ``` The important thing isn't the specific classes. These are just by way of illustrating the general idea; which can (and probably would) be adjusted to fit. Again, we may not need this quite yet. But, once we see copy & paste of method bodies, we'll know we need some refactoring. > Calculate return string length for literals & some string functions > ------------------------------------------------------------------- > > Key: DRILL-5419 > URL: https://issues.apache.org/jira/browse/DRILL-5419 > Project: Apache Drill > Issue Type: Bug > Affects Versions: 1.9.0 > Reporter: Arina Ielchiieva > Assignee: Arina Ielchiieva > Attachments: version_with_cast.JPG > > > Though Drill is schema-less and cannot determine in advance what the length > of the column should be but if query has an explicit type/length specified, > Drill should return correct column length. > For example, JDBC / ODBC Driver is ALWAYS returning 64K as the length of a > varchar or char even if casts are applied. > Changes: > *LITERALS* > String literals length is the same as actual literal length. > Example: for 'aaa' return length is 3. > *CAST* > Return length is the one indicated in cast expression. This also applies when > user has created view where each string columns was casted to varchar with > some specific length. > This length will be returned to the user without need to apply cast one more > time. Below mentioned functions can take leverage of underlying varchar > length and calculate return length. > *LOWER, UPPER, INITCAP, REVERSE, FIRST_VALUE, LAST_VALUE* > Return length is underlying column length, i.e. if column is known, the same > length will be returned. > Example: > lower(cast(col as varchar(30))) will return 30. > lower(col) will return max varchar length, since we don't know actual column > length. > *LAG, LEAD* > Return length is underlying column length but column type will be nullable. > *LPAD, RPAD* > Pads the string to the length specified. Return length is this specified > length. > *CONCAT, CONCAT OPERATOR (||)* > Return length is sum of underlying columns length. If length is greater then > varchar max length, varchar max length is returned. > *SUBSTR, SUBSTRING, LEFT, RIGHT* > Calculates return length according to each function substring rules, for > example, taking into account how many char should be substracted. > *IF EXPRESSIONS (CASE STATEMENT, COALESCE), UNION OPERATOR* > When combining string columns with different length, return length is max > from source columns. -- This message was sent by Atlassian JIRA (v6.3.15#6346)