Skip to content

Commit

Permalink
Merge #74006
Browse files Browse the repository at this point in the history
74006: sql: add support for DECLARE, FETCH, CLOSE CURSOR using internal executors r=jordanlewis a=jordanlewis

Touches #41412.

This PR implements the SQL CURSOR methods DECLARE, FETCH and CLOSE using streaming internal executors.

Here's the Postgres docs on DECLARE: https://www.postgresql.org/docs/current/sql-declare.html

Things it implements:

- DECLARE for forward-only cursors
- FETCH forward, relative, and absolute variants for forward-only cursors
- CLOSE a cursor
- pg_catalog.pg_cursors

Things it's missing:
- BINARY CURSOR support, which returns data in the Postgres binary format
- MOVE support, which allows advancing the cursor without returning any rows. This should be quite similar to FETCH.
- WITH HOLD support (allows keeping a cursor open for longer than a transaction by writing its results into a buffer)
- Scrollable cursor (reverse fetch) support, we'd have to implement this also by savings results into a buffer.
- FOR UPDATE support
- Respect for `SAVEPOINT`. Cursor definitions will not disappear if rolled back to a savepoint before they were created. But we also don't do this right for settings (see #69396) so I don't think this is a major problem.

Co-authored-by: Jordan Lewis <[email protected]>
  • Loading branch information
craig[bot] and jordanlewis committed Feb 21, 2022
2 parents 5b3067f + df20522 commit 2b9fef1
Show file tree
Hide file tree
Showing 30 changed files with 1,778 additions and 33 deletions.
2 changes: 2 additions & 0 deletions docs/generated/sql/bnf/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ FILES = [
"create_type",
"create_view_stmt",
"deallocate_stmt",
"declare_cursor_stmt",
"default_value_column_level",
"delete_stmt",
"discard_stmt",
Expand All @@ -108,6 +109,7 @@ FILES = [
"explainable_stmt",
"export_stmt",
"family_def",
"fetch_cursor_stmt",
"for_locking",
"foreign_key_column_level",
"foreign_key_table_level",
Expand Down
1 change: 1 addition & 0 deletions docs/generated/sql/bnf/close_cursor_stmt.bnf
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
close_cursor_stmt ::=
'CLOSE' 'ALL'
| 'CLOSE' cursor_name
2 changes: 2 additions & 0 deletions docs/generated/sql/bnf/declare_cursor_stmt.bnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare_cursor_stmt ::=
'DECLARE' cursor_name opt_binary opt_sensitivity opt_scroll 'CURSOR' opt_hold 'FOR' select_stmt
2 changes: 2 additions & 0 deletions docs/generated/sql/bnf/fetch_cursor_stmt.bnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fetch_cursor_stmt ::=
'FETCH' fetch_specifier
2 changes: 2 additions & 0 deletions docs/generated/sql/bnf/stmt.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ stmt ::=
| nonpreparable_set_stmt
| transaction_stmt
| close_cursor_stmt
| declare_cursor_stmt
| fetch_cursor_stmt
94 changes: 83 additions & 11 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ stmt ::=
| nonpreparable_set_stmt
| transaction_stmt
| close_cursor_stmt
| declare_cursor_stmt
| fetch_cursor_stmt
|

preparable_stmt ::=
Expand Down Expand Up @@ -122,6 +124,13 @@ transaction_stmt ::=

close_cursor_stmt ::=
'CLOSE' 'ALL'
| 'CLOSE' cursor_name

declare_cursor_stmt ::=
'DECLARE' cursor_name opt_binary opt_sensitivity opt_scroll 'CURSOR' opt_hold 'FOR' select_stmt

fetch_cursor_stmt ::=
'FETCH' fetch_specifier

alter_stmt ::=
alter_ddl_stmt
Expand Down Expand Up @@ -391,6 +400,40 @@ rollback_stmt ::=
abort_stmt ::=
'ABORT' opt_abort_mod

cursor_name ::=
name

opt_binary ::=
'BINARY'
|

opt_sensitivity ::=
'INSENSITIVE'
| 'ASENSITIVE'
|

opt_scroll ::=
'SCROLL'
| 'NO' 'SCROLL'
|

opt_hold ::=
'WITH' 'HOLD'
| 'WITHOUT' 'HOLD'
|

fetch_specifier ::=
cursor_name
| from_or_in cursor_name
| next_prior opt_from_or_in cursor_name
| forward_backward opt_from_or_in cursor_name
| opt_forward_backward signed_iconst64 opt_from_or_in cursor_name
| opt_forward_backward 'ALL' opt_from_or_in cursor_name
| 'ABSOLUTE' signed_iconst64 opt_from_or_in cursor_name
| 'RELATIVE' signed_iconst64 opt_from_or_in cursor_name
| 'FIRST' opt_from_or_in cursor_name
| 'LAST' opt_from_or_in cursor_name

alter_ddl_stmt ::=
alter_table_stmt
| alter_index_stmt
Expand Down Expand Up @@ -854,6 +897,7 @@ expr_list ::=

unreserved_keyword ::=
'ABORT'
| 'ABSOLUTE'
| 'ACTION'
| 'ACCESS'
| 'ADD'
Expand All @@ -862,12 +906,14 @@ unreserved_keyword ::=
| 'AGGREGATE'
| 'ALTER'
| 'ALWAYS'
| 'ASENSITIVE'
| 'AT'
| 'ATTRIBUTE'
| 'AUTOMATIC'
| 'AVAILABILITY'
| 'BACKUP'
| 'BACKUPS'
| 'BACKWARD'
| 'BEFORE'
| 'BEGIN'
| 'BINARY'
Expand Down Expand Up @@ -952,6 +998,7 @@ unreserved_keyword ::=
| 'FORCE'
| 'FORCE_INDEX'
| 'FORCE_ZIGZAG'
| 'FORWARD'
| 'FUNCTION'
| 'FUNCTIONS'
| 'GENERATED'
Expand All @@ -969,6 +1016,7 @@ unreserved_keyword ::=
| 'HASH'
| 'HIGH'
| 'HISTOGRAM'
| 'HOLD'
| 'HOUR'
| 'IDENTITY'
| 'IMMEDIATE'
Expand Down Expand Up @@ -1058,6 +1106,7 @@ unreserved_keyword ::=
| 'NOWAIT'
| 'NULLS'
| 'IGNORE_FOREIGN_KEYS'
| 'INSENSITIVE'
| 'OF'
| 'OFF'
| 'OIDS'
Expand Down Expand Up @@ -1091,6 +1140,7 @@ unreserved_keyword ::=
| 'PRECEDING'
| 'PREPARE'
| 'PRESERVE'
| 'PRIOR'
| 'PRIORITY'
| 'PRIVILEGES'
| 'PUBLIC'
Expand All @@ -1110,6 +1160,7 @@ unreserved_keyword ::=
| 'REGIONAL'
| 'REGIONS'
| 'REINDEX'
| 'RELATIVE'
| 'RELEASE'
| 'RELOCATE'
| 'RENAME'
Expand All @@ -1134,6 +1185,7 @@ unreserved_keyword ::=
| 'RUNNING'
| 'SCHEDULE'
| 'SCHEDULES'
| 'SCROLL'
| 'SETTING'
| 'SETTINGS'
| 'STATUS'
Expand Down Expand Up @@ -1332,6 +1384,29 @@ opt_abort_mod ::=
| 'WORK'
|

from_or_in ::=
'FROM'
| 'IN'

next_prior ::=
'NEXT'
| 'PRIOR'

opt_from_or_in ::=
from_or_in
|

forward_backward ::=
'FORWARD'
| 'BACKWARD'

opt_forward_backward ::=
forward_backward
|

signed_iconst64 ::=
signed_iconst

alter_table_stmt ::=
alter_onetable_stmt
| alter_split_stmt
Expand Down Expand Up @@ -1750,6 +1825,10 @@ opt_comma ::=
','
|

signed_iconst ::=
'ICONST'
| only_signed_iconst

alter_onetable_stmt ::=
'ALTER' 'TABLE' relation_expr alter_table_cmds
| 'ALTER' 'TABLE' 'IF' 'EXISTS' relation_expr alter_table_cmds
Expand Down Expand Up @@ -2334,6 +2413,10 @@ transaction_deferrable_mode ::=
'DEFERRABLE'
| 'NOT' 'DEFERRABLE'

only_signed_iconst ::=
'+' 'ICONST'
| '-' 'ICONST'

alter_table_cmds ::=
( alter_table_cmd ) ( ( ',' alter_table_cmd ) )*

Expand Down Expand Up @@ -2496,10 +2579,6 @@ opt_equal ::=
'='
|

signed_iconst ::=
'ICONST'
| only_signed_iconst

region_or_regions ::=
'REGIONS'

Expand Down Expand Up @@ -2559,10 +2638,6 @@ sortby ::=
| 'PRIMARY' 'KEY' table_name opt_asc_desc
| 'INDEX' table_name '@' index_name opt_asc_desc

only_signed_iconst ::=
'+' 'ICONST'
| '-' 'ICONST'

only_signed_fconst ::=
'+' 'FCONST'
| '-' 'FCONST'
Expand Down Expand Up @@ -3029,9 +3104,6 @@ storage_parameter_key_list ::=
partition_by_index ::=
partition_by

signed_iconst64 ::=
signed_iconst

func_name_no_crdb_extra ::=
type_function_name_no_crdb_extra
| prefixed_column_path
Expand Down
2 changes: 2 additions & 0 deletions pkg/gen/docs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ DOCS_SRCS = [
"//docs/generated/sql/bnf:create_type.bnf",
"//docs/generated/sql/bnf:create_view_stmt.bnf",
"//docs/generated/sql/bnf:deallocate_stmt.bnf",
"//docs/generated/sql/bnf:declare_cursor_stmt.bnf",
"//docs/generated/sql/bnf:default_value_column_level.bnf",
"//docs/generated/sql/bnf:delete_stmt.bnf",
"//docs/generated/sql/bnf:discard_stmt.bnf",
Expand All @@ -120,6 +121,7 @@ DOCS_SRCS = [
"//docs/generated/sql/bnf:explainable_stmt.bnf",
"//docs/generated/sql/bnf:export_stmt.bnf",
"//docs/generated/sql/bnf:family_def.bnf",
"//docs/generated/sql/bnf:fetch_cursor_stmt.bnf",
"//docs/generated/sql/bnf:for_locking.bnf",
"//docs/generated/sql/bnf:foreign_key_column_level.bnf",
"//docs/generated/sql/bnf:foreign_key_table_level.bnf",
Expand Down
12 changes: 12 additions & 0 deletions pkg/kv/kvclient/kvcoord/txn_coord_sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,18 @@ func (tc *TxnCoordSender) Step(ctx context.Context) error {
return tc.interceptorAlloc.txnSeqNumAllocator.stepLocked(ctx)
}

// SetReadSeqNum is part of the TxnSender interface.
func (tc *TxnCoordSender) SetReadSeqNum(seq enginepb.TxnSeq) error {
tc.mu.Lock()
defer tc.mu.Unlock()
if seq < 0 || seq > tc.interceptorAlloc.txnSeqNumAllocator.writeSeq {
return errors.AssertionFailedf("invalid read seq num < 0 || > writeSeq (%d): %d",
tc.interceptorAlloc.txnSeqNumAllocator.writeSeq, seq)
}
tc.interceptorAlloc.txnSeqNumAllocator.readSeq = seq
return nil
}

// ConfigureStepping is part of the TxnSender interface.
func (tc *TxnCoordSender) ConfigureStepping(
ctx context.Context, mode kv.SteppingMode,
Expand Down
Loading

0 comments on commit 2b9fef1

Please sign in to comment.