Comments (5)
The fact that the DDL statement(s) are executed automatically when a non-DDL statement is executed as part of the transaction, means that (an) invalid DDL statement(s) might cause a completely unrelated statement to fail.
It's true. As I said, it creates feeling that you're executing those DDLs in a transaction with other statements.
The generic Connection API specification therefore included the ability to define DDL batches using custom SQL statements. So if you want to execute a set of DDL statements as one batch, you would then execute the following set of statements:
Sounds good. If so, pumping up DDLs into an array will be redundant anyway (as I mentioned, I don't actually like how it looks in the code, so this custom statements idea sounds very good to me). With this in mind, I'm okay to raise an exception in case DDL is executed while in transaction 👍
from go-sql-spanner.
I second the idea to disallow running DDLs "inside" transaction first of all.
from go-sql-spanner.
As I see, Go implementation executes a DDL at once, meaning for one DDL it uses one separate request:
https://github.com/cloudspannerecosystem/go-sql-spanner/blob/d4bbe4fc855af9010b03ceb73895e07168b9ec29/driver.go#L288-L297
adminpb.UpdateDatabaseDdlRequest
however can accept an array of statements. Here I'd remind how we're processing DDL statements in Python.
When a DDL statement is executed, we're not sending it to the backend. Instead we insert it into internal list, pumping up all the DDLs. When a non-DDL statement is executed or the commit()
method is called, we're executing all the pumped up DDL statements with a single request. Note: in autocommit
mode DDL statement will be executed at once.
I can't say I like very much how it all looks in code, and in some cases it requires to call commit()
method to actually run DDL statements, which can create a feeling that DDLs are executed with transactions, but I propose to consider the variant, as sending DDLs in a grouped form seems to be more frugally to me then executing them one by one.
Python code where it all implemented:
https://github.com/googleapis/python-spanner/blob/b294dbf9e02e807883d4de515eada0f161ce9414/google/cloud/spanner_dbapi/cursor.py#L189-L207
So, finalizing it all from user's position: it creates a feeling that DDLs are executed with transactions. I'm okay with raising an error in case DDL is executed while transaction is in progress, but probably for users it'll be easier not to think about DDLs are executed outiside of transactions, and just work like they are a part of transactions.
from go-sql-spanner.
DDL Transactions
When a DDL statement is executed, we're not sending it to the backend. Instead we insert it into internal list, pumping up all the DDLs. When a non-DDL statement is executed or the commit() method is called, we're executing all the pumped up DDL statements with a single request. Note: in autocommit mode DDL statement will be executed at once.
I feel that that behavior is also slightly confusing, for two reasons:
- It still gives the idea that the DDL statements are part of the transaction, which they are not. Even if they are executed in a batch, they are not atomic. If one of the statements fail, some or all of the other statements may still be executed.
- The fact that the DDL statement(s) are executed automatically when a non-DDL statement is executed as part of the transaction, means that (an) invalid DDL statement(s) might cause a completely unrelated statement to fail. So if for example the following statements are executed as part of a transaction:
CREATE TABLE Singers (SingerId INT64, Name STRING(MAX)) PRIMARY KEY (SingerId);
CREATE TABLE Albums (AlbumId INT64, Title STRING(MAX)) PRIMARY KEY (Id); -- Note the mistyped Id column name
-- This will fail with an error that points to the CREATE TABLE Albums statement.
INSERT INTO Singers (id, Name) VALUES (1, 'Test');
DDL Batches
Batching DDL statements together is certainly something that you sometimes want, especially as it makes creating a large set of new tables or indexes a lot faster than executing them one by one. This is however different from DDL transactions as a transaction is something that a user would expect to be atomic.
The generic Connection API specification therefore included the ability to define DDL batches using custom SQL statements. So if you want to execute a set of DDL statements as one batch, you would then execute the following set of statements:
START BATCH DDL;
CREATE TABLE Singers (SingerId INT64, Name STRING(MAX)) PRIMARY KEY (SingerId);
CREATE TABLE Albums (AlbumId INT64, Title STRING(MAX)) PRIMARY KEY (AlbumId);
RUN BATCH;
A DDL batch is not intended to be atomic.
This feature would then be implemented as part of #16
from go-sql-spanner.
@olavloite Sorry for the late reply. I agree with (1) and (2) and should raise an exception in case DDL is executed in a transaction.
from go-sql-spanner.
Related Issues (20)
- Congratulations on the v1.0.0 release 🎉
- panic on DSN that does not match regexp HOT 1
- Support `driver.Valuer` in `CheckNamedValue()`
- CheckNamedValue: *int is not target? HOT 1
- Convert a value using the `Value()` method of my defined type
- How to register Spanner Driver to sqltrace? HOT 2
- ExecQuery with a DML statement with THEN RETURN in AutoCommit=true mode uses read-only transaction HOT 2
- go vet warning: self-assignment of sql to sql
- isDDL and removeStatementHint panic with invalid query
- Panic in TestBufferWriteMutations HOT 1
- examples do not compile
- Support *int
- flaky panic in TestSecondUpdateAborted_FirstResultUpdateCountChanged HOT 1
- Flaky panic in TestEmptyQueryAbortedTwice HOT 1
- Benchmarks
- feat: Add support for stale reads through client side statements HOT 1
- Allow adding session pool configuration to the connection string
- TestMinSessions failure HOT 1
- [Policy Bot] found one or more issues with this repository.
- Dependency Dashboard HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-sql-spanner.