[ https://issues.apache.org/jira/browse/DRILL-5419?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15986928#comment-15986928 ]
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_r113606681 --- Diff: common/src/main/java/org/apache/drill/common/types/Types.java --- @@ -636,43 +658,63 @@ public static String toString(final MajorType type) { /** * Get the <code>precision</code> of given type. - * @param majorType - * @return + * + * @param majorType major type + * @return precision value */ public static int getPrecision(MajorType majorType) { - MinorType type = majorType.getMinorType(); - - if (type == MinorType.VARBINARY || type == MinorType.VARCHAR) { - return 65536; - } - if (majorType.hasPrecision()) { return majorType.getPrecision(); } - return 0; + return isScalarStringType(majorType) ? MAX_VARCHAR_LENGTH : UNDEFINED; } /** * Get the <code>scale</code> of given type. - * @param majorType - * @return + * + * @param majorType major type + * @return scale value */ public static int getScale(MajorType majorType) { if (majorType.hasScale()) { return majorType.getScale(); } - return 0; + return UNDEFINED; } /** - * Is the given type column be used in ORDER BY clause? - * @param type - * @return + * Checks if the given type column be used in ORDER BY clause. + * + * @param type minor type + * @return true if type can be used in ORDER BY clause */ public static boolean isSortable(MinorType type) { // Currently only map and list columns are not sortable. return type != MinorType.MAP && type != MinorType.LIST; } + + /** + * Sets max precision from both types if these types are string scalar types. + * Sets max precision and scale from both types if these types are decimal types. + * + * @param leftType type from left side + * @param rightType type from right side + * @param typeBuilder type builder + * @return type builder + */ + public static MajorType.Builder calculateTypePrecisionAndScale(MajorType leftType, MajorType rightType, MajorType.Builder typeBuilder) { + boolean isScalarString = Types.isScalarStringType(leftType) && Types.isScalarStringType(rightType); + boolean isDecimal = CoreDecimalUtility.isDecimalType(leftType); + + if ((isScalarString || isDecimal) && leftType.hasPrecision() && rightType.hasPrecision()) { + typeBuilder.setPrecision(Math.max(leftType.getPrecision(), rightType.getPrecision())); + } + + if (isDecimal && leftType.hasScale() && rightType.hasScale()) { + typeBuilder.setScale(Math.max(leftType.getScale(), rightType.getScale())); --- End diff -- Not sure this is right. From [here](https://docs.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql): "Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. For example, the number 123.45 has a precision of 5 and a scale of 2." So, if we have: ``` Decimal9(9,0) Decimal9(9,9) ``` The result should be: ``` Decimal(18,9) ``` Or since this is out of range: ``` Decimal18(9,9) ``` > 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)