-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Decimal support for Postgres backend #10216
Changes from 40 commits
3ad23f1
48464af
6b694c7
7951326
1e3da12
aba8d48
145f9c0
8ce0dfe
e41bf5b
1200cce
8d94d5c
88e6714
631820c
d4ded95
24b265d
3ac81b7
a4b364b
2553533
c20d830
0e6bd39
5d7f770
1f97af7
49e50b3
c11e3f6
b62dcea
32fe09b
643c231
2dd3927
f66889e
7e748e1
60c494f
0eeba74
b9afc85
111fad1
4ae2902
4c4bc5b
b4f7115
4206905
358f89f
4815631
2c87d7a
bea018a
40f9b8d
357935b
8652753
6e7524f
47dc410
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ make_aggregate_column : DB_Table -> Aggregate_Column -> Text -> Dialect -> (Any | |
make_aggregate_column table aggregate as dialect infer_return_type problem_builder = | ||
is_non_empty_selector v = v.is_nothing.not && v.not_empty | ||
simple_aggregate op_kind columns = | ||
expression = SQL_Expression.Operation op_kind (columns.map c->c.expression) | ||
expression = dialect.cast_op_type op_kind columns (SQL_Expression.Operation op_kind (columns.map c->c.expression)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am adding the cast here, at the SQL level, instead of using And by doing it at this point, the regular type inference code will take care of the rest. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like the right place to call into this hook.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we still want to have this cast, we should at least ensure that we will not corrupt the data. We must add a test case where we have a column containing e.g. 2 rows with max I imagine if we get some kind of 'overflow' error - that will be OK. Ideally we should intercept this error and give the user a clear indication what happened and suggest that they can cast to a larger type (e.g. I think if we'd get a value that is modulo-truncated - that would be unacceptable as it would be a silent data corruption. But looking at a simple example:
I imagine we will likely just get an error, so it would just be good to intercept it and handle in a nice way for the user. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ooops, I have wrote this comment before reading There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, so do I understand correctly that the cast is needed to set the scale of the I thought that we are casting to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still, I guess it may be good to add such a test (Summing 2 rows that contain MAX INT64 values). It will be a good test verifying that our implementation is correct and does not cause data corruption in all kinds of DB backends (as I imagine how well the backends handle this may vary). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added this test. |
||
sql_type_ref = infer_return_type op_kind columns expression | ||
Internal_Column.Value as sql_type_ref expression | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,8 @@ import project.SQL_Type.SQL_Type | |
from project.Errors import SQL_Error, Unsupported_Database_Operation | ||
from project.Internal.IR.Operation_Metadata import Date_Period_Metadata | ||
|
||
polyglot java import java.sql.Types | ||
|
||
## PRIVATE | ||
|
||
The dialect of PostgreSQL databases. | ||
|
@@ -195,6 +197,24 @@ type Postgres_Dialect | |
Illegal_State.Error "The type computed by our logic is Char, but the Database computed a non-text type ("+db_type.to_display_text+"). This should never happen and should be reported as a bug in the Database library." | ||
False -> column | ||
|
||
## PRIVATE | ||
Add an extra cast to adjust the output type of certain operations with certain arguments. | ||
cast_op_type self (op_kind:Text) (args:(Vector Internal_Column)) (expression:SQL_Expression) = | ||
is_bigint ic = ic.sql_type_reference.get.typeid == Types.BIGINT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. personally I prefer to call it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
is_int ic = | ||
typeid = ic.sql_type_reference.get.typeid | ||
typeid == Types.SMALLINT || typeid == Types.INTEGER || typeid == Types.BIGINT | ||
|
||
cast_to = case op_kind of | ||
"SUM" -> | ||
if is_bigint (args.at 0) then "numeric(1000,0)" else Nothing | ||
"AVG" -> | ||
if is_int (args.at 0) then "float8" else Nothing | ||
_ -> Nothing | ||
|
||
if cast_to.is_nothing then expression else | ||
SQL_Expression.Operation "CAST" [expression, SQL_Expression.Literal cast_to] | ||
|
||
## PRIVATE | ||
prepare_fetch_types_query : SQL_Expression -> Context -> SQL_Statement | ||
prepare_fetch_types_query self expression context = | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems very useful, I imagine I may want to use a hook like this in the Snowflake dialect as well to handle some weird edge cases.
I'd appreciate if we can make this comment a bit more detailed to understand how it is supposed to be used.
I'd like to know:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done