Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id BF274200B69 for ; Sat, 6 Aug 2016 00:03:07 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id BDF26160AAC; Fri, 5 Aug 2016 22:03:07 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 1AC9C160A8E for ; Sat, 6 Aug 2016 00:03:06 +0200 (CEST) Received: (qmail 71336 invoked by uid 500); 5 Aug 2016 22:03:06 -0000 Mailing-List: contact dev-help@drill.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@drill.apache.org Delivered-To: mailing list dev@drill.apache.org Received: (qmail 71319 invoked by uid 99); 5 Aug 2016 22:03:06 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 05 Aug 2016 22:03:05 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C1C60EC22C; Fri, 5 Aug 2016 22:03:05 +0000 (UTC) From: paul-rogers To: dev@drill.apache.org Reply-To: dev@drill.apache.org References: In-Reply-To: Subject: [GitHub] drill issue #517: DRILL-4704 fix Content-Type: text/plain Message-Id: <20160805220305.C1C60EC22C@git1-us-west.apache.org> Date: Fri, 5 Aug 2016 22:03:05 +0000 (UTC) archived-at: Fri, 05 Aug 2016 22:03:07 -0000 Github user paul-rogers commented on the issue: https://github.com/apache/drill/pull/517 Based on above discussion, I played around with the proposed solution. The following takes into consideration the max precision of both the input and output types. It DOES NOT handle truncation properly (but nor do any of the other solutions.) Here is the revised code: if (precision.value <= 0) { <#-- // since input precision is nonpositive, calculate precision for this integer value long precisionTmp = in.value == 0 ? 1 : in.value; // precision for value 0 will be 1 int precisionCounter = 0; while (precisionTmp != 0) { ++precisionCounter; precisionTmp /= 10; } out.precision = precisionCounter; --> // Since precision is not provided, select one appropriate for the // largest integer value and the target decimal type. // Note: if the integer is too large for the target precision, silent // truncation of the highest part of the number will occur. This is // obviously bad. What should happen is we shift scale and discard // the low-order digits. // That is, if we convert 123,456,789,012 to Dec9, the result is // 456,789,012 which is very obviously very wrong. It should be // 123,456,789,000. <#-- A correct solution requires a modification of the code commented out above. --> <#-- Precision needed by the largest from type value. --> <#if type.from.equals( "Int" )> <#assign inPrec = 10> <#elseif type.from.equals( "BigInt" )> <#assign inPrec = 19> <#else> <#-- Yes, create invalid syntax: that way the compiler will tell us we missed a type. --> <#assign inPrec = "Unexpected from type: ${type.from}"> <#-- Maximum precision allowed by the to type. --> <#if type.to.startsWith("Decimal9")> <#assign maxPrec = 9> <#elseif type.to.startsWith("Decimal18")> <#assign maxPrec = 18> <#elseif type.to.startsWith("Decimal28")> <#assign maxPrec = 28> <#elseif type.to.startsWith("Decimal38")> <#assign maxPrec = 38> <#else> <#-- Yes, create invalid syntax: that way the compiler will tell us we missed a type. --> <#assign maxPrec = "Unexpected to type: ${type.to}"> <#-- Note that this calculation is done here, rather than in static variables, because static members are not allowed for this function. --> <#if inPrec < maxPrec> // Maximum precision needed by the largest ${type.from} value. out.precision = ${inPrec}; <#else> // Maximum precision allowed by the ${type.to} type. out.precision = ${maxPrec}; } else { // since input precision is positive, assume it is correct, and use it out.precision = (int) precision.value; out.scale = (int) scale.value; } --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastructure@apache.org or file a JIRA ticket with INFRA. ---