-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Add Spanner connector #16724
base: master
Are you sure you want to change the base?
Add Spanner connector #16724
Conversation
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
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.
Please add a documentation and tests (connector test, type mapping test, product test and etc). You can refer to #8323
@ebyhr sure, thank you for the reference. I will keep enhancing the PR |
…y keys,not null fields, timestamp field options etc.
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
Could you change to draft PR if it's not ready for review? |
@@ -0,0 +1,660 @@ | |||
package io.trino.plugin.spanner; |
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.
The license header is missing.
case Types.CHAR: | ||
case Types.VARCHAR: | ||
case Types.NVARCHAR: | ||
case Types.LONGVARCHAR: | ||
case Types.LONGNVARCHAR: |
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.
All conditions are really needed?
case Types.BINARY: | ||
case Types.VARBINARY: | ||
case Types.LONGVARBINARY: |
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.
All conditions are really needed?
import io.trino.testing.MaterializedResult; | ||
import org.testng.annotations.Test; | ||
|
||
public class TestSpannerDataTypes |
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.
Rename to TestSpannerTypeMapping
MaterializedResult execute = queryRunner.execute("select * from spanner.default.dtest"); | ||
System.out.println(execute); | ||
|
||
} |
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.
Please cover all types in this test.
@Inject | ||
public SpannerTableProperties() | ||
{ | ||
System.out.println("CALLED TABLE PROPERTIES "); |
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.
Remove.
MaterializedResult drop = queryRunner.execute("DROP TABLE spanner.default.dept"); | ||
System.out.println(drop); | ||
|
||
System.out.println("DONE"); |
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.
Please remove System.out.println
.
@@ -196,6 +196,7 @@ | |||
<module>testing/trino-testing-resources</module> | |||
<module>testing/trino-testing-services</module> | |||
<module>testing/trino-tests</module> | |||
<module>plugin/trino-spanner</module> |
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.
Please update core/trino-server/src/main/provisio/trino.xml
as well.
DATE, | ||
dateReadFunctionUsingLocalDate(), | ||
spannerDateWriteFunctionUsingLocalDate())); | ||
case Types.TIMESTAMP: |
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.
I would recommend removing support for TIMESTAMP
in this PR. We can add the type later.
return timestamp.toInstant().toEpochMilli() * 1000; | ||
}, | ||
(statement, index, value) -> statement.setTimestamp(index, new java.sql.Timestamp(value / 1000)))); | ||
case Types.BOOLEAN: |
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.
Move before Types.SMALLINT
.
@ebyhr changed to draft as not ready for review yet |
…modes as insert and upsert
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
@ebyhr Spanner JDBC does not allow upserts when inserting duplicate records with the same key. So i changed spanner sink from JdbcSink to write via Spanner Mutations API which can do upserts. So right now spanner reads everything over JDBC but writes are made via Spanner API. What is the best practise her? Should reads also change to Spanner API? or we can allow reads and writes to be different API's as in this case |
@ebyhr Another reason why I changed from JDBC sink to Spanner mutations API-based sink is that randomly after creating a table JDBC would throw an error that the table is not ready in the spanner. That was automatically taken care of by the spanner mutations api. For this see https://cloud.google.com/spanner/docs/information-schema#columns Spanner state |
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.
Nice work!
resultSet.getString("TABLE_NAME")); | ||
} | ||
|
||
public static void sleep() |
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.
What's the usage about this method?
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.
Nah just random testing will remove that
int jdbcType = typeHandle.getJdbcType(); | ||
String jdbcTypeName = typeHandle.getJdbcTypeName() | ||
.orElseThrow(() -> new TrinoException(JDBC_ERROR, "Type name is missing: " + typeHandle)); | ||
System.out.println("Column mapping for type " + typeHandle); |
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.
Remove system.out.println
switch (jdbcType) { | ||
case Types.BOOLEAN: | ||
return Optional.of(StandardColumnMappings.booleanColumnMapping()); | ||
case Types.SMALLINT: |
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.
How about add a type mapping test? you can refer TestIgniteTypeMapping
as a example
@Override | ||
public Collection<String> listSchemas(Connection connection) | ||
{ | ||
Set<String> schemas = new HashSet<>(Collections.singleton(DEFAULT_SCHEMA)); |
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.
User ImmutableSet.Builder
Set<String> schemas = new HashSet<>(Collections.singleton(DEFAULT_SCHEMA)); | ||
try (ResultSet resultSet = connection.getMetaData().getSchemas(null, null)) { | ||
while (resultSet.next()) { | ||
schemas.add(resultSet.getString(1)); |
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.
How about use resultSet.getString(name)
} | ||
|
||
@Override | ||
public List<JdbcColumnHandle> getColumns(ConnectorSession session, JdbcTableHandle tableHandle) |
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.
Why override?
{ | ||
} | ||
|
||
@Override |
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.
Why override?
public SpannerClient(BaseJdbcConfig config, SpannerConfig spannerConfig, JdbcStatisticsConfig statisticsConfig, ConnectionFactory connectionFactory, QueryBuilder queryBuilder, TypeManager typeManager, IdentifierMapping identifierMapping, RemoteQueryModifier queryModifier) | ||
{ | ||
super("`", connectionFactory, queryBuilder, config.getJdbcTypesMappedToVarchar(), identifierMapping, queryModifier, true); | ||
this.config = spannerConfig; |
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.
requireNonNull(spannerConfig, "spannerConfig is null")
throws SQLException | ||
{ | ||
String schema = resultSet.getString("TABLE_SCHEM"); | ||
if (schema != null && schema.equals("")) { |
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.
Strings.emptyToNull
} | ||
|
||
@Override | ||
public TableStatistics getTableStatistics(ConnectorSession session, JdbcTableHandle handle) |
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.
Same, why override?
@taher-cldcvr If the write side is much more complicated than the read part, maybe we can support read for Spanner connector first cc @ebyhr |
It is not complicated as it is already implemented and works well. I want to review and need help testing the writing side thoroughly |
Thank you @chenjian2664 for the review. I will address the comments and add more test cases. |
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
Need help with test case @ebyhr , @chenjian2664 I am getting the following error when testing for test type mapping org.assertj.core.error.MultipleAssertionsError:
to contain exactly in any order:
Dont understand what i did wrong here |
Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla |
@findepi @chenjian2664 @ebyhr @ragnard I cannot understand what is going wrong with this test case. Please can you guys help me |
@ebyhr @findepi can you guys help me understand what I am doing wrong here? I feel like this is a very simple assertion error of expecting elements in list. I cannot figure out what needs to change. |
Description
Fixes #13053
Release notes
(x) Release notes are required, with the following suggested text: