-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
sql: sequences created by SERIAL
have weird semantics with regards to database
#51090
Comments
Hi @ajwerner, please add a C-ategory label to your issue. Check out the label system docs. While you're here, please consider adding an A- label to help keep our repository tidy. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan. |
@arulajmani you'll probably find this one interesting. In postgres this works better because |
FWIW I recall there was a recent discussion to disallow cross-db references altogether. |
That's true. You can, however, take the above example and apply it to user-defined schemas and search path and if we don't change anything, we'll still have a problem. This issue has several dimensions
postgres=# SELECT 16441::regclass;
regclass
----------
foo Imagine today we do the following: s INT8 NOT NULL DEFAULT nextval('foo_s_seq':::STRING) I have two related concrete proposals that both have the same first:
A. In the default expression we just use an integer cast to a regclass. For example: s INT8 NOT NULL DEFAULT nextval(60::regclass) B. In the default expression we generate for columns using s INT8 NOT NULL DEFAULT nextval(crdb_internal.create_regclass(60, 'foo_s_seq')) |
Nice find! I guess this is currently blocking us from a logictest configuration that uses sequences for serial normalization. I tried creating a sequence with a fully qualified name which would force the sequence to be created in the same database as the table, and storing the fully qualified name in the default expression, and that seems to fix the problem. I'll add some tests and put a PR out. |
Yeah, that proposal makes sense. In the absence of a |
Can you check that doesn't explode if/when the db gets renamed. |
That's a great point. We'll need to deal with this when renaming database (and schemas for UDS). |
It doesn't implode, but it will prohibit renaming databases that use
With this rename issue + the fact that we'll be supporting UDS very soon, I'm leaning more towards Andrew's proposal of solving this by having default expressions store something more robust and overloading To me it seems like rendering the regclass to its string representation is the major issue there. I'm not too familiar with how/how much regclass compatibility we support, but this seems hard. I wonder if as an intermediate step there is value in storing the sequence's descriptor ID and name (at creation) in the default expression which will allow us to implement Alternative B in @ajwerner's proposal above. We could be displaying stale information if the sequence is renamed, or we could continue to disallow sequence renames like we do today. |
I'm happy with B as a first step though do want to ask about sequence renames. It seems to me like getting sequence renames right isn't too terrible if all we need to do is update the table[s] which reference it. I was much more worried about needing to traverse all of the tables when renaming a database or schema. |
Alright here's a perhaps real pathway forward, when do we need to know the name of referenced descriptor? Seems like only for display purposes. So the latest thinking on this proposal is these steps that each get us closer to postgres
Only 2 seems hard. This could be pretty good. This proposal is in many ways exactly what's asked for in #22212. Relates to #10083 as we'd want to do the same thing in view queries with names. |
In fact making table ID stable would be good for pg compatibility. UI tools that use pg_catalog get confused if you truncate a table (and rotate the ID) from "under" them. |
in positive news here, we did the truncate thing so the path to a brighter future is now clearer. There are open questions with regards to migrations of existing expressions. I'm rather open to not migrating them. Ideally we'd make the "default" overload for the function into the regclass so that new expressions which utilize the string get resolved to regclasses so that the same expression ends up with the better serialization. For existing string serialization the regclass resolution at runtime should end up doing exactly what we do today. That might be wishful thinking, I don't know enough about the way the overloads work out with the constant expressions. Worst case we could put some hacks in place when to prefer resolving the strings to regclass integers when looking to serialize the sequence operations into descriptors. |
@otan says that the issue in #53819 is a duplicate, here's the symptom
I don't actually understand why they are marked as duplicate to each other (see my question in #53819 (comment) ) and thus would appreciate an explanation thanks |
The suggested solution to resolving this (#54410) is the same. |
|
(re my point 2: if there are separate causes but common solutions, we can have 1 PR that "closes" 2 or more issues at a time) |
59396: sql: overload sequence operators to accept a regclass r=the-ericwang35 a=the-ericwang35 sql: overload sequence operators to accept a regclass Previously, sequence operators (nextval, setval, currval) only accepted a string to refer to the referenced sequence. This patch allows these operators to accept a regclass as well. Tests were also added to verify this. This is the first step to fix this issue: #51090. Release note (sql change): overload sequence operators to accept a regclass Co-authored-by: Eric Wang <[email protected]>
60957: sql: add backup/restore tests for sequences r=the-ericwang35 a=the-ericwang35 This patch just adds tests for backup/restore with respect to sequences. Now that all new sequences are referenced by ID and can be renamed, we want to test that previously created sequences are not affected, and still follow the old rules (i.e. cannot be renamed and and are referenced by their names. Part of #51090 In the future, we'll want to convert these old sequences to new sequences (i.e. can be renamed and are referenced by ID, see #60942) which means these tests will need to change, but for now, we'll keep the old sequences as is. Release note (None): add backup/restore tests for sequences 60972: sql: error if SURVIVE is set with no regions r=ajstorm a=otan Release justification: bug fix to new functionality Release note: None 60993: colexec: remove duplication around bazel utility functions r=yuzefovich a=yuzefovich Previously, we had essentially duplicated `.bzl` files in two packages that need to generate code using `execgen`, but this can be avoided by defining a separate `.bzl` file as an extension used in both places. Release note: None 61008: TeamCity: update build agents to use the latest sudo r=rail a=rail Release note: None 61024: authors: add erikgrinaker r=erikgrinaker a=erikgrinaker Release note: none 61025: authors: add fqazi to authors r=fqazi a=fqazi authors: add fqazi to authors Release note: None 61026: authors: add abarganier to authors r=abarganier a=abarganier Release note: None Co-authored-by: Eric Wang <[email protected]> Co-authored-by: Oliver Tan <[email protected]> Co-authored-by: Yahor Yuzefovich <[email protected]> Co-authored-by: Rail Aliiev <[email protected]> Co-authored-by: Erik Grinaker <[email protected]> Co-authored-by: Faizan Qazi <[email protected]> Co-authored-by: Alex Barganier <[email protected]>
61126: sql: add version upgrade test for sequences r=ajwerner a=the-ericwang35 This patch just adds some version upgrade tests for sequences. Now that all new sequences are referenced by ID and can be renamed, we want to test that previously created sequences are not affected, and still follow the old rules (i.e. cannot be renamed and and are referenced by their names. This test creates some sequences in 20.2.5, upgrades the cluster, and verifies this behaviour. Part of #51090. In the future, we'll want to convert these old sequences to new sequences (i.e. can be renamed and are referenced by ID, see #60942) which means these tests will need to change, but for now, we'll keep the old sequences as is. Release note: None Release justification: only adds tests for existing functionality 62203: sql: capture sequences used in cast exprs r=ajwerner a=the-ericwang35 Previously, `GetSequenceFromFunc` only looked for `*tree.DString` and `*tree.DOid`. However, it's also possible for the sequence to be given via a `*tree.CastExpr` (for example, `nextval('s'::regclass)`). In this case, the sequence was not being captured, which meant no back references were created and no sequence encoding was done. This PR addresses this by adding an additional case to capture these sequences. This will probably need to be backported. Release note: None Co-authored-by: Eric Wang <[email protected]>
Describe the problem
When we create
SERIAL
types and we haveserial_normalization
set to'sql_sequence'
we construct a new sequence. Unfortunately, the sequence we construct is in the current database rather than the database of the table. This leads to strange semantics where the table can only be written to if the current session is in the database of the sequence.The problem here is that we use the session's database to resolve the sequence rather than the table's. In postgres, IIUC, the table's database and schema are used to resolve the sequence.
To Reproduce
Even worse, if I create a sequence in that database with that name, it'll get used:
Expected behavior
The
SERIAL
column will work regardless of which database the current session is in. Furthermore, as we move to user-defined schemas, it should refer to a single sequence regardless of the current session'ssearch_path
.The text was updated successfully, but these errors were encountered: