Skip to content
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

Fix incorrect information in schema change + prepared statement limitations #18551

Merged
merged 7 commits into from
Jun 3, 2024
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
+----+-----------+
| id | name |
+----+-----------+
| 1 | Max Roach |
+----+-----------+
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
+----+-----------+
| id | name |
+----+-----------+
| 1 | Max Roach |
+----+-----------+
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
+----+-----------+
| id | name |
+----+-----------+
| 1 | Max Roach |
+----+-----------+
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
+----+-----------+
| id | name |
+----+-----------+
| 1 | Max Roach |
+----+-----------+
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include copy-clipboard.html %}
{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
id | name
-----+------------
1 | Max Roach
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
id | name
-----+------------
1 | Max Roach
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
When the schema of a table targeted by a prepared statement changes before the prepared statement is executed, CockroachDB allows the prepared statement to return results based on the changed table schema, for example:
When the schema of a table targeted by a prepared statement changes after the prepared statement is created, future executions of the prepared statement could result in an error. For example, adding a column to a table referenced in a prepared statement with a `SELECT *` clause will result in an error:

{% include_cached copy-clipboard.html %}
~~~ sql
> CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE users (id INT PRIMARY KEY);
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> PREPARE prep1 AS SELECT * FROM users;
PREPARE prep1 AS SELECT * FROM users;
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> ALTER TABLE users ADD COLUMN name STRING;
ALTER TABLE users ADD COLUMN name STRING;
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> INSERT INTO users VALUES (1, 'Max Roach');
INSERT INTO users VALUES (1, 'Max Roach');
~~~

{% include_cached copy-clipboard.html %}
~~~ sql
> EXECUTE prep1;
EXECUTE prep1;
~~~

~~~
id | name
-----+------------
1 | Max Roach
(1 row)
ERROR: cached plan must not change result type
SQLSTATE: 0A000
~~~

It's therefore recommended to **not** use `SELECT *` in queries that will be repeated, via prepared statements or otherwise.

Also, a prepared [`INSERT`](insert.html), [`UPSERT`](upsert.html), or [`DELETE`](delete.html) statement acts inconsistently when the schema of the table being written to is changed before the prepared statement is executed:

- If the number of columns has increased, the prepared statement returns an error but nonetheless writes the data.
- If the number of columns remains the same but the types have changed, the prepared statement writes the data and does not return an error.
It's therefore recommended to explicitly list result columns instead of using `SELECT *` in prepared statements, when possible.
Loading
Loading