This is an automated email from the ASF dual-hosted git repository.

csringhofer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit d03ffc70f2da0e313846d1595b1577824808f9da
Author: jasonmfehr <[email protected]>
AuthorDate: Thu Feb 15 13:01:26 2024 -0800

    IMPALA-12824: Adds built-in functions prettyprint_duration and 
prettyprint_bytes.
    
    The prettyprint_duration function takes an integer input containing a
    number of nanoseconds and returns a human readable value breaking down
    the input by hours, minutes, seconds, milliseconds, microseconds, and
    nanoseconds.
    
    The prettyprint_bytes function takes an integer input containing a
    number of bytes and returns a human readable values breaking down the
    input by gigabytes, megabytes, kilobytes, and bytes.
    
    Functionality tests were added to the existing expr-test suite that
    tests built-in functions.
    
    Functional-query workloads were added in two new .test files under the
    testdata directory to exercise these two new functions. Corresponding
    pytests were added to run the tests in these new .test files.
    
    Benchmarks were added to expr-benchmark, and new benchmarks were
    generated with a release build running on a machine with the cpu
    Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz.
    
    Documentation was added to the built-in string functions docs.
    
    Change-Id: I3e76632ce21ad2ca5df474160338699a542a6913
    Reviewed-on: http://gerrit.cloudera.org:8080/21038
    Reviewed-by: Impala Public Jenkins <[email protected]>
    Tested-by: Impala Public Jenkins <[email protected]>
---
 be/src/benchmarks/expr-benchmark.cc                | 112 +++++++++--------
 be/src/exprs/expr-test.cc                          |  64 ++++++++++
 be/src/exprs/string-functions-ir.cc                |  59 +++++++++
 be/src/exprs/string-functions.h                    |  14 +++
 common/function-registry/impala_functions.py       |   8 ++
 docs/topics/impala_functions.xml                   |  14 +++
 docs/topics/impala_string_functions.xml            |  77 ++++++++++++
 .../queries/QueryTest/prettyprint-bytes.test       | 134 +++++++++++++++++++++
 .../queries/QueryTest/prettyprint-duration.test    | 120 ++++++++++++++++++
 tests/query_test/test_prettyprint_bytes.py         |  35 ++++++
 tests/query_test/test_prettyprint_duration.py      |  35 ++++++
 11 files changed, 619 insertions(+), 53 deletions(-)

diff --git a/be/src/benchmarks/expr-benchmark.cc 
b/be/src/benchmarks/expr-benchmark.cc
index 54b173eb5..dfc7ad27c 100644
--- a/be/src/benchmarks/expr-benchmark.cc
+++ b/be/src/benchmarks/expr-benchmark.cc
@@ -530,62 +530,66 @@ Benchmark* BenchmarkConditionalFunctions(bool codegen) {
 // StringFn:                  Function  iters/ms   10%ile   50%ile   90%ile    
 10%ile     50%ile     90%ile
 //                                                                          
(relative) (relative) (relative)
 // 
---------------------------------------------------------------------------------------------------------
-//                              length                209      210      212    
     1X         1X         1X
-//                          substring1                153      153      154    
  0.73X     0.729X     0.727X
-//                          substring2                173      174      176    
 0.827X     0.826X      0.83X
-//                                left                159      160      161    
 0.763X     0.762X     0.758X
-//                               right                160      160      161    
 0.764X     0.763X     0.758X
-//                               lower               74.9     75.6     76.3    
 0.358X      0.36X      0.36X
-//                               upper               76.5     77.4       78    
 0.366X     0.369X     0.368X
-//                             reverse                108      109      110    
 0.515X     0.519X      0.52X
-//                                trim                194      195      197    
  0.93X      0.93X     0.929X
-//                               ltrim                217      218      221    
  1.04X      1.04X      1.04X
-//                               rtrim                217      220      221    
  1.04X      1.05X      1.04X
-//                               space                147      148      149    
 0.702X     0.704X     0.703X
-//                               ascii                294      296      298    
  1.41X      1.41X      1.41X
-//                               instr               95.1     95.5     96.5    
 0.455X     0.455X     0.455X
-//                              locate               93.7     94.1     94.6    
 0.448X     0.448X     0.446X
-//                             locate2               98.8       99     99.5    
 0.473X     0.471X     0.469X
-//                              concat                129      130      131    
 0.616X     0.618X     0.618X
-//                             concat2               99.4      100      102    
 0.475X     0.478X     0.479X
-//                            concatws                262      264      267    
  1.25X      1.26X      1.26X
-//                           concatws2               97.5     98.4     99.2    
 0.467X     0.468X     0.468X
-//                              repeat               83.8     84.9     85.6    
 0.401X     0.404X     0.403X
-//                                lpad                 81     81.7     82.2    
 0.387X     0.389X     0.388X
-//                                rpad               81.5     82.4     82.7    
  0.39X     0.392X      0.39X
-//                         find_in_set                140      142      143    
  0.67X     0.674X     0.673X
-//                      regexp_extract               19.9     20.1     20.1    
0.0953X    0.0957X    0.0949X
-//                      regexp_replace               1.43     1.44     1.44   
0.00686X   0.00687X    0.0068X
-//
+//                              length                420      425      427    
     1X         1X         1X
+//                          substring1                372      376      380    
 0.886X     0.886X     0.889X
+//                          substring2                406      410      415    
 0.969X     0.966X      0.97X
+//                                left                370      372      377    
 0.882X     0.875X     0.883X
+//                               right                369      373      378    
  0.88X     0.879X     0.884X
+//                               lower                159      161      162    
 0.379X     0.379X     0.379X
+//                               upper                157      157      159    
 0.373X      0.37X     0.373X
+//                             reverse                266      271      273    
 0.635X     0.637X     0.638X
+//                                trim                446      452      455    
  1.06X      1.06X      1.06X
+//                               ltrim                546      556      559    
   1.3X      1.31X      1.31X
+//                               rtrim                545      553      556    
   1.3X       1.3X       1.3X
+//                               space                372      376      380    
 0.888X     0.886X     0.889X
+//                               ascii                809      817      826    
  1.93X      1.92X      1.93X
+//                               instr                220      223      225    
 0.524X     0.526X     0.526X
+//                              locate                217      218      219    
 0.517X     0.512X     0.511X
+//                             locate2                229      230      232    
 0.545X     0.542X     0.543X
+//                              concat                316      318      322    
 0.753X      0.75X     0.753X
+//                             concat2                257      260      263    
 0.613X     0.611X     0.615X
+//                            concatws                593      597      599    
  1.41X      1.41X       1.4X
+//                           concatws2                228      229      232    
 0.543X     0.539X     0.543X
+//                              repeat                208      209      212    
 0.495X     0.493X     0.497X
+//                                lpad                169      170      170    
 0.403X       0.4X     0.399X
+//                                rpad                167      169      170    
 0.397X     0.397X     0.397X
+//                         find_in_set                321      323      325    
 0.765X     0.761X      0.76X
+//                      regexp_extract                 42     42.8       43    
   0.1X     0.101X     0.101X
+//                      regexp_replace               2.94     2.96        3   
0.00701X   0.00698X   0.00702X
+//                prettyprint_duration               18.3     18.6     18.7    
0.0437X    0.0439X    0.0438X
+//                  prettyprint_bytes                9.54     9.72     9.75    
0.0227X    0.0229X    0.0228X
+// 
 // StringFnCodegen:           Function  iters/ms   10%ile   50%ile   90%ile    
 10%ile     50%ile     90%ile
 //                                                                          
(relative) (relative) (relative)
 // 
---------------------------------------------------------------------------------------------------------
-//                              length                826      834      836    
     1X         1X         1X
-//                          substring1                297      300      302    
  0.36X      0.36X     0.362X
-//                          substring2                777      785      790    
 0.941X     0.942X     0.945X
-//                                left                296      299      301    
 0.359X     0.359X      0.36X
-//                               right                297      300      303    
  0.36X     0.359X     0.362X
-//                               lower                102      103      104    
 0.123X     0.123X     0.125X
-//                               upper                105      106      107    
 0.127X     0.127X     0.128X
-//                             reverse                161      165      168    
 0.194X     0.198X       0.2X
-//                                trim                425      427      432    
 0.514X     0.513X     0.517X
-//                               ltrim                561      564      569    
 0.679X     0.677X     0.681X
-//                               rtrim                584      587      594    
 0.707X     0.705X     0.711X
-//                               space                213      215      217    
 0.258X     0.258X      0.26X
-//                               ascii                822      829      836    
 0.996X     0.994X         1X
-//                               instr                215      217      219    
 0.261X      0.26X     0.262X
-//                              locate                214      217      218    
 0.259X      0.26X     0.261X
-//                             locate2                226      228      230    
 0.274X     0.274X     0.275X
-//                              concat                210      214      216    
 0.254X     0.257X     0.258X
-//                             concat2                189      191      193    
 0.229X      0.23X     0.231X
-//                            concatws                777      784      790    
 0.941X     0.941X     0.945X
-//                           concatws2                160      162      163    
 0.194X     0.194X     0.196X
-//                              repeat                159      161      164    
 0.193X     0.194X     0.196X
-//                                lpad                212      214      216    
 0.257X     0.257X     0.258X
-//                                rpad                212      214      216    
 0.257X     0.257X     0.259X
-//                         find_in_set                276      278      280    
 0.334X     0.333X     0.335X
-//                      regexp_extract               20.4     20.5     20.8    
0.0247X    0.0246X    0.0248X
-//                      regexp_replace               1.43     1.47     1.47   
0.00174X   0.00176X   0.00176X
+//                              length                461      466      471    
     1X         1X         1X
+//                          substring1                372      377      380    
 0.806X     0.809X     0.808X
+//                          substring2                369      376      378    
 0.802X     0.806X     0.802X
+//                                left                367      369      375    
 0.797X     0.792X     0.797X
+//                               right                351      356      359    
 0.761X     0.764X     0.763X
+//                               lower                160      161      162    
 0.347X     0.345X     0.344X
+//                               upper                156      157      157    
 0.339X     0.336X     0.334X
+//                             reverse                272      275      277    
 0.591X     0.591X     0.588X
+//                                trim                445      450      453    
 0.966X     0.966X     0.963X
+//                               ltrim                551      558      563    
   1.2X       1.2X       1.2X
+//                               rtrim                544      552      557    
  1.18X      1.18X      1.18X
+//                               space                374      377      380    
 0.811X     0.808X     0.807X
+//                               ascii                805      813      823    
  1.75X      1.74X      1.75X
+//                               instr                220      223      224    
 0.478X     0.479X     0.476X
+//                              locate                219      220      220    
 0.475X     0.471X     0.468X
+//                             locate2                225      227      231    
 0.489X     0.487X      0.49X
+//                              concat                316      319      322    
 0.686X     0.683X     0.684X
+//                             concat2                258      260      264    
  0.56X     0.557X      0.56X
+//                            concatws                593      598      602    
  1.29X      1.28X      1.28X
+//                           concatws2                227      229      232    
 0.493X      0.49X     0.493X
+//                              repeat                203      205      208    
 0.441X     0.439X     0.441X
+//                                lpad                169      170      170    
 0.367X     0.364X     0.362X
+//                                rpad                169      169      170    
 0.366X     0.363X     0.361X
+//                         find_in_set                320      323      325    
 0.694X     0.693X     0.691X
+//                      regexp_extract               42.2       43     43.2    
0.0915X    0.0922X    0.0918X
+//                      regexp_replace               2.89     2.94        3   
0.00626X   0.00631X   0.00637X
+//                prettyprint_duration               18.3     18.6     18.7    
0.0398X      0.04X    0.0397X
+//                  prettyprint_bytes                9.55     9.72     9.74    
0.0207X    0.0208X    0.0207X
 Benchmark* BenchmarkStringFunctions(bool codegen) {
   Benchmark* suite = new Benchmark(BenchmarkName("StringFn", codegen));
   BENCHMARK("length", "length('Hello World!')");
@@ -614,6 +618,8 @@ Benchmark* BenchmarkStringFunctions(bool codegen) {
   BENCHMARK("find_in_set", "find_in_set('ab', 'abc,ad,ab,ade,cde')");
   BENCHMARK("regexp_extract", "regexp_extract('abxcy1234a', 'a.x.y.*a', 0)");
   BENCHMARK("regexp_replace", "regexp_replace('axcaycazc', '', 'r')");
+  BENCHMARK("prettyprint_duration", "prettyprint_duration(123456789)");
+  BENCHMARK("prettyprint_bytes", "prettyprint_bytes(987654321)");
   return suite;
 }
 
diff --git a/be/src/exprs/expr-test.cc b/be/src/exprs/expr-test.cc
index 52b6b0a3d..f487b4ed0 100644
--- a/be/src/exprs/expr-test.cc
+++ b/be/src/exprs/expr-test.cc
@@ -4347,6 +4347,70 @@ TEST_P(ExprTest, StringFunctions) {
         "jaro-winkler boost threshold values can range between 0.0 and 1.0\n");
   }
 
+  // Test prettyprint_duration
+  TestStringValue("prettyprint_duration(-1)", "-1.000ns");
+  TestStringValue("prettyprint_duration(0)", "0.000ns");
+  TestStringValue("prettyprint_duration(1234)", "1.234us");
+  TestStringValue("prettyprint_duration(123456789012)", "2m3s");
+  TestStringValue("prettyprint_duration(12345678901292)", "3h25m");
+  TestIsNull("prettyprint_duration(NULL)", TYPE_STRING);
+
+  // Test at the type boundaries for tinyint.
+  TestStringValue("prettyprint_duration(127)", "127.000ns");
+  TestStringValue("prettyprint_duration(128)", "128.000ns");
+  TestStringValue("prettyprint_duration(-128)", "-128.000ns");
+  TestStringValue("prettyprint_duration(-129)", "-129.000ns");
+
+  // Test at the type boundaries for smallint.
+  TestStringValue("prettyprint_duration(32767)", "32.767us");
+  TestStringValue("prettyprint_duration(32768)", "32.768us");
+  TestStringValue("prettyprint_duration(-32768)", "-32768.000ns");
+  TestStringValue("prettyprint_duration(-32769)", "-32769.000ns");
+
+  // Test at the type boundaries for int.
+  TestStringValue("prettyprint_duration(2147483647)", "2s147ms");
+  TestStringValue("prettyprint_duration(2147483648)", "2s147ms");
+  TestStringValue("prettyprint_duration(-2147483648)", "-2147483648.000ns");
+  TestStringValue("prettyprint_duration(-2147483649)", "-2147483649.000ns");
+
+  // Test at the type boundaries for bigint.
+  TestStringValue("prettyprint_duration(9223372036854775807)", "2562047h47m");
+  TestStringValue("prettyprint_duration(-9223372036854775808)",
+      "-9223372036854775808.000ns");
+
+  // Test prettyprint_bytes
+  TestStringValue("prettyprint_bytes(-1234)", "-1.21 KB");
+  TestStringValue("prettyprint_bytes(0)", "0");
+  TestStringValue("prettyprint_bytes(1)", "1.00 B");
+  TestStringValue("prettyprint_bytes(123)", "123.00 B");
+  TestStringValue("prettyprint_bytes(1024)", "1.00 KB");
+  TestStringValue("prettyprint_bytes(1234567)", "1.18 MB");
+  TestStringValue("prettyprint_bytes(1234567901)", "1.15 GB");
+  TestStringValue("prettyprint_bytes(12345679012345)", "11497.81 GB");
+  TestIsNull("prettyprint_bytes(NULL)", TYPE_STRING);
+
+  // Test at the type boundaries for tinyint.
+  TestStringValue("prettyprint_bytes(127)", "127.00 B");
+  TestStringValue("prettyprint_bytes(128)", "128.00 B");
+  TestStringValue("prettyprint_bytes(-128)", "-128.00 B");
+  TestStringValue("prettyprint_bytes(-129)", "-129.00 B");
+
+  // Test at the type boundaries for smallint.
+  TestStringValue("prettyprint_bytes(32767)", "32.00 KB");
+  TestStringValue("prettyprint_bytes(32768)", "32.00 KB");
+  TestStringValue("prettyprint_bytes(-32768)", "-32.00 KB");
+  TestStringValue("prettyprint_bytes(-32769)", "-32.00 KB");
+
+  // Test at the type boundaries for int.
+  TestStringValue("prettyprint_bytes(2147483647)", "2.00 GB");
+  TestStringValue("prettyprint_bytes(2147483648)", "2.00 GB");
+  TestStringValue("prettyprint_bytes(-2147483648)", "-2.00 GB");
+  TestStringValue("prettyprint_bytes(-2147483649)", "-2.00 GB");
+
+  // Test at the type boundaries for bigint.
+  TestStringValue("prettyprint_bytes(9223372036854775807)", "8589934592.00 
GB");
+  TestStringValue("prettyprint_bytes(-9223372036854775808)", "-8589934592.00 
GB");
+
   TestStringValue("substring('Hello', 1)", "Hello");
   TestStringValue("substring('Hello', -2)", "lo");
   TestStringValue("substring('Hello', cast(0 as bigint))", "");
diff --git a/be/src/exprs/string-functions-ir.cc 
b/be/src/exprs/string-functions-ir.cc
index de8c8d7a5..c78a4a5bc 100644
--- a/be/src/exprs/string-functions-ir.cc
+++ b/be/src/exprs/string-functions-ir.cc
@@ -27,6 +27,7 @@
 
 #include "exprs/anyval-util.h"
 #include "exprs/scalar-expr.h"
+#include "gen-cpp/Metrics_types.h"
 #include "gutil/strings/charset.h"
 #include "gutil/strings/substitute.h"
 #include "runtime/string-value.inline.h"
@@ -1888,4 +1889,62 @@ IntVal StringFunctions::DamerauLevenshtein(
   ctx->Free(reinterpret_cast<uint8_t*>(rows));
   return IntVal(result);
 }
+
+template <typename T>
+static StringVal prettyPrint(FunctionContext* context, const T& int_val,
+    const TUnit::type& unit) {
+  if (int_val.is_null) {
+    return StringVal::null();
+  }
+
+  const string& fmt_str = PrettyPrinter::Print(int_val.val, unit);
+
+  StringVal result(context, fmt_str.size());
+  if (UNLIKELY(result.is_null)) return StringVal::null();
+  uint8_t* ptr = result.ptr;
+  memcpy(ptr, fmt_str.c_str(), fmt_str.size());
+
+  return result;
+}
+
+StringVal StringFunctions::PrettyPrintDuration(FunctionContext* context,
+    const BigIntVal& duration_us) {
+  return prettyPrint(context, duration_us, TUnit::TIME_NS);
+}
+
+StringVal StringFunctions::PrettyPrintDuration(FunctionContext* context,
+    const IntVal& duration_us) {
+  return prettyPrint(context, duration_us, TUnit::TIME_NS);
+}
+
+StringVal StringFunctions::PrettyPrintDuration(FunctionContext* context,
+    const SmallIntVal& duration_us) {
+  return prettyPrint(context, duration_us, TUnit::TIME_NS);
+}
+
+StringVal StringFunctions::PrettyPrintDuration(FunctionContext* context,
+    const TinyIntVal& duration_us) {
+  return prettyPrint(context, duration_us, TUnit::TIME_NS);
+}
+
+StringVal StringFunctions::PrettyPrintMemory(FunctionContext* context,
+    const BigIntVal& bytes) {
+  return prettyPrint(context, bytes, TUnit::BYTES);
+}
+
+StringVal StringFunctions::PrettyPrintMemory(FunctionContext* context,
+    const IntVal& bytes) {
+  return prettyPrint(context, bytes, TUnit::BYTES);
+}
+
+StringVal StringFunctions::PrettyPrintMemory(FunctionContext* context,
+    const SmallIntVal& bytes) {
+  return prettyPrint(context, bytes, TUnit::BYTES);
+}
+
+StringVal StringFunctions::PrettyPrintMemory(FunctionContext* context,
+    const TinyIntVal& bytes) {
+  return prettyPrint(context, bytes, TUnit::BYTES);
+}
+
 }
\ No newline at end of file
diff --git a/be/src/exprs/string-functions.h b/be/src/exprs/string-functions.h
index 3b6da4f56..0d15490dd 100644
--- a/be/src/exprs/string-functions.h
+++ b/be/src/exprs/string-functions.h
@@ -236,6 +236,20 @@ class StringFunctions {
       const StringVal& s2, const DoubleVal& scaling_factor,
       const DoubleVal& boost_threshold);
 
+  /// Converts nanoseconds stored as an integer value into human readable time 
durations.
+  /// For example, 2147483647 nanoseconds is converted to "2s147ms".
+  static StringVal PrettyPrintDuration(FunctionContext*, const BigIntVal& 
duration_us);
+  static StringVal PrettyPrintDuration(FunctionContext*, const IntVal& 
duration_us);
+  static StringVal PrettyPrintDuration(FunctionContext*, const SmallIntVal& 
duration_us);
+  static StringVal PrettyPrintDuration(FunctionContext*, const TinyIntVal& 
duration_us);
+
+  /// Converts bytes stored as an integer value into human readable memory 
measurements.
+  /// For example, 123456789012 bytes is converted to "114.98 GB".
+  static StringVal PrettyPrintMemory(FunctionContext*, const BigIntVal& bytes);
+  static StringVal PrettyPrintMemory(FunctionContext*, const IntVal& bytes);
+  static StringVal PrettyPrintMemory(FunctionContext*, const SmallIntVal& 
bytes);
+  static StringVal PrettyPrintMemory(FunctionContext*, const TinyIntVal& 
bytes);
+
  private:
   static uint64_t re2_mem_limit_;
 
diff --git a/common/function-registry/impala_functions.py 
b/common/function-registry/impala_functions.py
index 71d48814c..d59398414 100644
--- a/common/function-registry/impala_functions.py
+++ b/common/function-registry/impala_functions.py
@@ -610,6 +610,14 @@ visible_functions = [
   [['parse_url'], 'STRING', ['STRING', 'STRING', 'STRING'], 
'impala::StringFunctions::ParseUrlKey',
    
'_ZN6impala15StringFunctions15ParseUrlPrepareEPN10impala_udf15FunctionContextENS2_18FunctionStateScopeE',
    
'_ZN6impala15StringFunctions13ParseUrlCloseEPN10impala_udf15FunctionContextENS2_18FunctionStateScopeE'],
+   [['prettyprint_duration'], 'STRING', ['BIGINT'], 
'impala::StringFunctions::PrettyPrintDuration'],
+   [['prettyprint_duration'], 'STRING', ['INT'], 
'impala::StringFunctions::PrettyPrintDuration'],
+   [['prettyprint_duration'], 'STRING', ['SMALLINT'], 
'impala::StringFunctions::PrettyPrintDuration'],
+   [['prettyprint_duration'], 'STRING', ['TINYINT'], 
'impala::StringFunctions::PrettyPrintDuration'],
+   [['prettyprint_bytes'], 'STRING', ['BIGINT'], 
'impala::StringFunctions::PrettyPrintMemory'],
+   [['prettyprint_bytes'], 'STRING', ['INT'], 
'impala::StringFunctions::PrettyPrintMemory'],
+   [['prettyprint_bytes'], 'STRING', ['SMALLINT'], 
'impala::StringFunctions::PrettyPrintMemory'],
+   [['prettyprint_bytes'], 'STRING', ['TINYINT'], 
'impala::StringFunctions::PrettyPrintMemory'],
 # Netezza compatibility char functions
   [['chr'], 'STRING', ['INT'], 'impala::StringFunctions::Chr'],
   [['btrim'], 'STRING', ['STRING'], 'impala::StringFunctions::Trim',
diff --git a/docs/topics/impala_functions.xml b/docs/topics/impala_functions.xml
index 3f2a8f83a..4aad813e3 100644
--- a/docs/topics/impala_functions.xml
+++ b/docs/topics/impala_functions.xml
@@ -1036,6 +1036,20 @@ under the License.
                 >PRECISION</xref>
             </entry>
           </row>
+          <row>
+            <entry>
+              <xref href=
+                
"impala_string_functions.xml#string_functions/prettyprint_duration">
+                PRETTYPRINT_DURATION</xref>
+            </entry>
+          </row>
+          <row>
+            <entry>
+              <xref href=
+                
"impala_string_functions.xml#string_functions/prettyprint_bytes">
+                PRETTYPRINT_BYTES</xref>
+            </entry>
+          </row>
           <row>
             <entry>
               <xref
diff --git a/docs/topics/impala_string_functions.xml 
b/docs/topics/impala_string_functions.xml
index c9fa41c35..5fd723d60 100644
--- a/docs/topics/impala_string_functions.xml
+++ b/docs/topics/impala_string_functions.xml
@@ -182,6 +182,14 @@ under the License.
         <xref href="#string_functions/parse_url">PARSE_URL</xref>
       </li>
 
+      <li>
+        <xref 
href="#string_functions/prettyprint_duration">PRETTYPRINT_DURATION</xref>
+      </li>
+
+      <li>
+        <xref 
href="#string_functions/prettyprint_bytes">PRETTYPRINT_BYTES</xref>
+      </li>
+
       <li>
         <xref href="#string_functions/regexp_escape">REGEXP_ESCAPE</xref>
       </li>
@@ -1130,6 +1138,75 @@ select instr('foo bar bletch', 'b', 1, 2);
 
       </dlentry>
 
+      <dlentry id="prettyprint_duration">
+
+        <dt>
+          PRETTYPRINT_DURATION(TINYINT / SMALLINT / INT / BIGINT nanoseconds)
+        </dt>
+
+        <dd>
+          <b>Purpose:</b> Formats numeric nanoseconds in a human readable 
manner.
+          <p>
+            <b>Return type:</b> <codeph>STRING</codeph>
+          </p>
+
+          <p>
+            <b>Usage notes:</b>
+          </p>
+
+          <p>
+            Negative durations are not fully supported. No conversion to 
milliseconds/seconds/minutes/hours
+            is performed. The input value is directly returned with the 
<codeph>ns</codeph> suffix added.
+          </p>
+
+          <p>
+            <b>Examples:</b>
+          </p>
+
+          <p>
+<codeblock>
+select prettyprint_duration(1), prettyprint_duration(12345678), 
prettyprint_duration(1234567890123), prettyprint_duration(98765432141451), 
prettyprint_duration(-436512);
+
++-------------------------+--------------------------------+-------------------------------------+--------------------------------------+-------------------------------+
+| prettyprint_duration(1) | prettyprint_duration(12345678) | 
prettyprint_duration(1234567890123) | prettyprint_duration(98765432141451) | 
prettyprint_duration(-436512) |
++-------------------------+--------------------------------+-------------------------------------+--------------------------------------+-------------------------------+
+| 1.000ns                 | 12.345ms                       | 20m34s            
                  | 27h26m                               | -436512.000ns        
         |
++-------------------------+--------------------------------+-------------------------------------+--------------------------------------+-------------------------------+
+</codeblock>
+          </p>
+        </dd>
+      </dlentry>
+
+      <dlentry id="prettyprint_bytes">
+
+        <dt>
+          PRETTYPRINT_BYTES(TINYINT / SMALLINT / INT / BIGINT bytes)
+        </dt>
+
+        <dd>
+          <b>Purpose:</b> Formats numeric bytes in a human readable manner.
+          <p>
+            <b>Return type:</b> <codeph>STRING</codeph>
+          </p>
+
+          <p>
+            <b>Examples:</b>
+          </p>
+
+          <p>
+<codeblock>
+select prettyprint_bytes(1), prettyprint_bytes(12345678), 
prettyprint_bytes(1234567890), prettyprint_bytes(1234567890123);
+
++-----------------------+------------------------------+--------------------------------+-------------------------------+
+| prettyprint_bytes(1) | prettyprint_bytes(12345678) | 
prettyprint_bytes(1234567890) | prettyprint_bytes(1234567890123) |
++----------------------+-----------------------------+-------------------------------+----------------------------------+
+| 1.00 B               | 11.77 MB                    | 1.15 GB                 
      | 1149.78 GB                       |
++----------------------+-----------------------------+-------------------------------+----------------------------------+
+</codeblock>
+          </p>
+        </dd>
+      </dlentry>
+
       <dlentry rev="3.0" id="regexp_escape">
 
         <dt>
diff --git 
a/testdata/workloads/functional-query/queries/QueryTest/prettyprint-bytes.test 
b/testdata/workloads/functional-query/queries/QueryTest/prettyprint-bytes.test
new file mode 100644
index 000000000..77c7ef8ca
--- /dev/null
+++ 
b/testdata/workloads/functional-query/queries/QueryTest/prettyprint-bytes.test
@@ -0,0 +1,134 @@
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-1234);
+---- TYPES
+string
+---- RESULTS
+'-1.21 KB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(0);
+---- TYPES
+string
+---- RESULTS
+'0'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(1);
+---- TYPES
+string
+---- RESULTS
+'1.00 B'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(1234567901);
+---- TYPES
+string
+---- RESULTS
+'1.15 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(127);
+---- TYPES
+string
+---- RESULTS
+'127.00 B'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(128);
+---- TYPES
+string
+---- RESULTS
+'128.00 B'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-128);
+---- TYPES
+string
+---- RESULTS
+'-128.00 B'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-129);
+---- TYPES
+string
+---- RESULTS
+'-129.00 B'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(32767);
+---- TYPES
+string
+---- RESULTS
+'32.00 KB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(32768);
+---- TYPES
+string
+---- RESULTS
+'32.00 KB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-32768);
+---- TYPES
+string
+---- RESULTS
+'-32.00 KB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-32769);
+---- TYPES
+string
+---- RESULTS
+'-32.00 KB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(2147483647);
+---- TYPES
+string
+---- RESULTS
+'2.00 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(2147483648);
+---- TYPES
+string
+---- RESULTS
+'2.00 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-2147483648);
+---- TYPES
+string
+---- RESULTS
+'-2.00 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-2147483649);
+---- TYPES
+string
+---- RESULTS
+'-2.00 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(9223372036854775807);
+---- TYPES
+string
+---- RESULTS
+'8589934592.00 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(-9223372036854775808);
+---- TYPES
+string
+---- RESULTS
+'-8589934592.00 GB'
+====
+---- QUERY
+SELECT PRETTYPRINT_BYTES(NULL);
+---- TYPES
+string
+---- RESULTS
+'NULL'
+====
diff --git 
a/testdata/workloads/functional-query/queries/QueryTest/prettyprint-duration.test
 
b/testdata/workloads/functional-query/queries/QueryTest/prettyprint-duration.test
new file mode 100644
index 000000000..76cc30690
--- /dev/null
+++ 
b/testdata/workloads/functional-query/queries/QueryTest/prettyprint-duration.test
@@ -0,0 +1,120 @@
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-1);
+---- TYPES
+string
+---- RESULTS
+'-1.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(0);
+---- TYPES
+string
+---- RESULTS
+'0.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(127);
+---- TYPES
+string
+---- RESULTS
+'127.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(128);
+---- TYPES
+string
+---- RESULTS
+'128.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-128);
+---- TYPES
+string
+---- RESULTS
+'-128.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-129);
+---- TYPES
+string
+---- RESULTS
+'-129.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(32767);
+---- TYPES
+string
+---- RESULTS
+'32.767us'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(32768);
+---- TYPES
+string
+---- RESULTS
+'32.768us'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-32768);
+---- TYPES
+string
+---- RESULTS
+'-32768.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-32769);
+---- TYPES
+string
+---- RESULTS
+'-32769.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(2147483647);
+---- TYPES
+string
+---- RESULTS
+'2s147ms'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(2147483648);
+---- TYPES
+string
+---- RESULTS
+'2s147ms'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-2147483648);
+---- TYPES
+string
+---- RESULTS
+'-2147483648.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-2147483649);
+---- TYPES
+string
+---- RESULTS
+'-2147483649.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(9223372036854775807);
+---- TYPES
+string
+---- RESULTS
+'2562047h47m'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(-9223372036854775808);
+---- TYPES
+string
+---- RESULTS
+'-9223372036854775808.000ns'
+====
+---- QUERY
+SELECT PRETTYPRINT_DURATION(NULL);
+---- TYPES
+string
+---- RESULTS
+'NULL'
+====
diff --git a/tests/query_test/test_prettyprint_bytes.py 
b/tests/query_test/test_prettyprint_bytes.py
new file mode 100644
index 000000000..119c88bfe
--- /dev/null
+++ b/tests/query_test/test_prettyprint_bytes.py
@@ -0,0 +1,35 @@
+# 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.
+
+from __future__ import absolute_import, division, print_function
+from tests.common.impala_test_suite import ImpalaTestSuite
+import pytest
+
+
+class TestPrettyPrintBytes(ImpalaTestSuite):
+  """Tests the built-in function prettyprint_bytes."""
+
+  @classmethod
+  def get_workload(self):
+    return 'functional-query'
+
+  def test_prettyprint_bytes(self, vector):
+    if (vector.get_value('table_format').file_format != 'text'
+        or vector.get_value('table_format').compression_codec != 'none'):
+      # No need to run this test on all file formats
+      pytest.skip()
+    self.run_test_case('QueryTest/prettyprint-bytes', vector)
diff --git a/tests/query_test/test_prettyprint_duration.py 
b/tests/query_test/test_prettyprint_duration.py
new file mode 100644
index 000000000..39b2e2218
--- /dev/null
+++ b/tests/query_test/test_prettyprint_duration.py
@@ -0,0 +1,35 @@
+# 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.
+
+from __future__ import absolute_import, division, print_function
+from tests.common.impala_test_suite import ImpalaTestSuite
+import pytest
+
+
+class TestPrettyPrintDuration(ImpalaTestSuite):
+  """Tests the built-in function prettyprint_duration."""
+
+  @classmethod
+  def get_workload(self):
+    return 'functional-query'
+
+  def test_prettyprint_duration(self, vector):
+    if (vector.get_value('table_format').file_format != 'text'
+        or vector.get_value('table_format').compression_codec != 'none'):
+      # No need to run this test on all file formats
+      pytest.skip()
+    self.run_test_case('QueryTest/prettyprint-duration', vector)


Reply via email to