Skip to content

[function](round) compute accurate round value by decimal#14946

Merged
Gabriel39 merged 5 commits intoapache:masterfrom
Gabriel39:round_fn
Dec 13, 2022
Merged

[function](round) compute accurate round value by decimal#14946
Gabriel39 merged 5 commits intoapache:masterfrom
Gabriel39:round_fn

Conversation

@Gabriel39
Copy link
Contributor

@Gabriel39 Gabriel39 commented Dec 8, 2022

Proposed changes

before:
image

after:
image

Problem summary

Describe your changes.

Checklist(Required)

  1. Does it affect the original behavior:
    • Yes
    • No
    • I don't know
  2. Has unit tests been added:
    • Yes
    • No
    • No Need
  3. Has document been added or modified:
    • Yes
    • No
    • No Need
  4. Does it need to update dependencies:
    • Yes
    • No
  5. Are there any changes that cannot be rolled back:
    • Yes (If Yes, please explain WHY)
    • No

Further comments

If this is a relatively large or complex change, kick off the discussion at dev@doris.apache.org by explaining why you chose the solution you did and what alternatives you considered, etc...

@github-actions github-actions bot added area/planner Issues or PRs related to the query planner area/sql/function Issues or PRs related to the SQL functions area/vectorization kind/test labels Dec 8, 2022
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

return x / scale * scale;
}
case RoundingMode::Floor: {
if (x < 0) x -= scale - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
if (x < 0) x -= scale - 1;
if (x < 0) { x -= scale - 1;
}

return x / scale * scale;
}
case RoundingMode::Ceil: {
if (x >= 0) x += scale - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
if (x >= 0) x += scale - 1;
if (x >= 0) { x += scale - 1;
}

return x / scale * scale;
}
case RoundingMode::Round: {
if (x < 0) x -= scale;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
if (x < 0) x -= scale;
if (x < 0) { x -= scale;
}

break;
case TieBreakingMode::Bankers: {
T quotient = (x + scale / 2) / scale;
if (quotient * scale == x + scale / 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
if (quotient * scale == x + scale / 2)
if (quotient * scale == x + scale / 2) {

be/src/vec/functions/round.h:92:

-                 else
+                 } else

if (quotient * scale == x + scale / 2)
// round half to even
x = ((quotient + (x < 0)) & ~1) * scale;
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
else
else {

be/src/vec/functions/round.h:94:

-                     x = quotient * scale;
+                     x = quotient * scale;
+ }

}

bool use_default_implementation_for_constants() const override { return true; }
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]

    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
    ^

}

bool use_default_implementation_for_constants() const override { return true; }
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: braces around scalar initializer [clang-diagnostic-braced-scalar-init]

Suggested change
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
ColumnNumbers get_arguments_that_are_always_constant() const override { return 1; }

bool use_default_implementation_for_constants() const override { return true; }
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }

Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'Block' [clang-diagnostic-error]

    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
                                                  ^

bool use_default_implementation_for_constants() const override { return true; }
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }

Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]

    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
                                                                      ^


Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
size_t result, size_t /*input_rows_count*/) override {
const ColumnWithTypeAndName& column = block.get_by_position(arguments[0]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'ColumnWithTypeAndName' [clang-diagnostic-error]

        const ColumnWithTypeAndName& column = block.get_by_position(arguments[0]);
              ^

@hello-stephen
Copy link
Contributor

hello-stephen commented Dec 8, 2022

TeamCity pipeline, clickbench performance test result:
the sum of best hot time: 35.38 seconds
load time: 480 seconds
storage size: 17123356232 Bytes
https://doris-community-test-1308700295.cos.ap-hongkong.myqcloud.com/tmp/20221212043532_clickbench_pr_61804.html

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

return x / scale * scale;
}
case RoundingMode::Floor: {
if (x < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
if (x < 0) {
if (x < 0) { x -= scale - 1;
}

x -= scale - 1;
}
return x / scale * scale;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
}
if (x >= 0) { x += scale - 1;
}

case RoundingMode::Ceil: {
if (x >= 0) {
x += scale - 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
}
if (x < 0) { x -= scale;
}

if (x < 0) {
x -= scale;
}
switch (tie_breaking_mode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
switch (tie_breaking_mode) {
if (quotient * scale == x + scale / 2) {

be/src/vec/functions/round.h:92:

-                 else
+                 } else

switch (tie_breaking_mode) {
case TieBreakingMode::Auto:
x = (x + scale / 2) / scale * scale;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: statement should be inside braces [readability-braces-around-statements]

Suggested change
break;
else {

be/src/vec/functions/round.h:94:

-                     x = quotient * scale;
+                     x = quotient * scale;
+ }


Int64 scale64 = scale_field.get<Int64>();
if (scale64 > std::numeric_limits<Int16>::max() ||
scale64 < std::numeric_limits<Int16>::min()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]

    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
    ^


Int64 scale64 = scale_field.get<Int64>();
if (scale64 > std::numeric_limits<Int16>::max() ||
scale64 < std::numeric_limits<Int16>::min()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: braces around scalar initializer [clang-diagnostic-braced-scalar-init]

Suggested change
scale64 < std::numeric_limits<Int16>::min()) {
ColumnNumbers get_arguments_that_are_always_constant() const override { return 1; }

if (scale64 > std::numeric_limits<Int16>::max() ||
scale64 < std::numeric_limits<Int16>::min()) {
return Status::InvalidArgument("Scale argument for function {} is too large: {}", name,
scale64);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'Block' [clang-diagnostic-error]

    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
                                                  ^

if (scale64 > std::numeric_limits<Int16>::max() ||
scale64 < std::numeric_limits<Int16>::min()) {
return Status::InvalidArgument("Scale argument for function {} is too large: {}", name,
scale64);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]

    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
                                                                      ^

return Status::InvalidArgument("Scale argument for function {} is too large: {}", name,
scale64);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'ColumnWithTypeAndName' [clang-diagnostic-error]

        const ColumnWithTypeAndName& column = block.get_by_position(arguments[0]);
              ^

static size_t prepare(size_t scale) { return scale; }

/// Integer overflow is Ok.
static ALWAYS_INLINE T computeImpl(T x, T scale) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compute_impl

Copy link
Contributor

@HappenLee HappenLee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions github-actions bot added the approved Indicates a PR has been approved by one committer. label Dec 12, 2022
@github-actions
Copy link
Contributor

PR approved by at least one committer and no changes requested.

@github-actions
Copy link
Contributor

PR approved by anyone and no changes requested.

@yangzhg
Copy link
Member

yangzhg commented Dec 20, 2022

round(16.025,2) should be 16.03 not 16.03000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. area/planner Issues or PRs related to the query planner area/sql/function Issues or PRs related to the SQL functions area/vectorization dev/1.2.1-merged kind/test reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants