3
3
# DuckDB Redis Client Extension
4
4
This extension provides Redis client functionality for DuckDB, allowing you to interact with a Redis server directly from SQL queries.
5
5
6
- > Experimental: USE AT YOUR OWN RISK!
7
- <img src="https://github.com/user-attachments/assets/46a5c546-7e9b-42c7-87f4-bc8defe674e0" width=250 />
8
-
9
- # DuckDB Redis Client Extension
10
- This extension provides Redis client functionality for DuckDB, allowing you to interact with a Redis server directly from SQL queries.
11
-
12
6
> Experimental: USE AT YOUR OWN RISK!
13
7
14
8
## Features
15
9
Currently supported Redis operations:
16
10
- String operations: ` GET ` , ` SET `
17
11
- Hash operations: ` HGET ` , ` HSET `
18
12
- List operations: ` LPUSH ` , ` LRANGE `
19
- - Batch operations: ` MGET ` , ` SCAN `
13
+
20
14
21
15
## Installation
22
16
``` sql
23
17
INSTALL redis FROM community;
24
18
LOAD redis;
25
- INSTALL redis FROM community;
26
- LOAD redis;
27
19
```
28
20
29
21
## Usage
30
22
### Setting up Redis Connection
31
23
First, create a secret to store your Redis connection details:
24
+
32
25
``` sql
33
26
-- Create a Redis connection secret
34
- CALL redis_create_secret(' my_redis' , {
35
- ' host' : ' localhost' ,
36
- ' port' : ' 6379' ,
37
- ' password' : ' optional_password'
38
- });
39
-
40
- -- For cloud Redis services (e.g., Redis Labs)
41
- CALL redis_create_secret(' redis_cloud' , {
42
- ' host' : ' redis-xxxxx.cloud.redislabs.com' ,
43
- ' port' : ' 16379' ,
44
- ' password' : ' your_password'
45
- });
27
+ CREATE SECRET IF NOT EXISTS redis (
28
+ TYPE redis,
29
+ PROVIDER config,
30
+ host ' localhost' ,
31
+ port ' 6379' ,
32
+ password ' optional_password'
33
+ );
34
+
35
+ -- Create a Redis cloud connection secret
36
+ CREATE SECRET IF NOT EXISTS redis (
37
+ TYPE redis,
38
+ PROVIDER config,
39
+ host ' redis-1234.ec2.redns.redis-cloud.com' ,
40
+ port ' 16959' ,
41
+ password ' xxxxxx'
42
+ );
46
43
```
47
44
48
- ### String Operations
49
45
### String Operations
50
46
``` sql
51
47
-- Set a value
52
- SELECT redis_set(' user:1' , ' John Doe' , ' my_redis ' ) as result;
48
+ SELECT redis_set(' user:1' , ' John Doe' , ' redis ' ) as result;
53
49
54
50
-- Get a value
55
- SELECT redis_get(' user:1' , ' my_redis ' ) as user_name;
51
+ SELECT redis_get(' user:1' , ' redis ' ) as user_name;
56
52
57
53
-- Set multiple values in a query
58
54
INSERT INTO users (id, name)
59
- SELECT id, redis_set(
60
- INSERT INTO users (id, name)
61
55
SELECT id, redis_set(
62
56
' user:' || id::VARCHAR ,
63
57
name,
64
58
' my_redis'
65
- ' my_redis'
66
59
)
67
60
FROM new_users;
68
61
```
69
62
70
63
### Hash Operations
71
64
``` sql
72
65
-- Set hash fields
73
- SELECT redis_hset(
' user:1' ,
' email' ,
' [email protected] ' ,
' my_redis ' );
74
- SELECT redis_hset(' user:1' , ' age' , ' 30' , ' my_redis ' );
66
+ SELECT redis_hset(
' user:1' ,
' email' ,
' [email protected] ' ,
' redis ' );
67
+ SELECT redis_hset(' user:1' , ' age' , ' 30' , ' redis ' );
75
68
76
69
-- Get hash field
77
- SELECT redis_hget(' user:1' , ' email' , ' my_redis ' ) as email;
70
+ SELECT redis_hget(' user:1' , ' email' , ' redis ' ) as email;
78
71
79
72
-- Store user profile as hash
80
73
WITH profile(id, field, value) AS (
@@ -87,51 +80,52 @@ SELECT redis_hset(
87
80
' user:' || id::VARCHAR ,
88
81
field,
89
82
value,
90
- ' my_redis '
83
+ ' redis '
91
84
)
92
85
FROM profile;
93
86
```
94
87
95
88
### List Operations
96
89
``` sql
97
90
-- Push items to list
98
- SELECT redis_lpush(' mylist' , ' first_item' , ' my_redis ' );
99
- SELECT redis_lpush(' mylist' , ' second_item' , ' my_redis ' );
91
+ SELECT redis_lpush(' mylist' , ' first_item' , ' redis ' );
92
+ SELECT redis_lpush(' mylist' , ' second_item' , ' redis ' );
100
93
101
94
-- Get range from list (returns comma-separated values)
102
95
-- Get all items (0 to -1 means start to end)
103
- SELECT redis_lrange(' mylist' , 0 , - 1 , ' my_redis ' ) as items;
96
+ SELECT redis_lrange(' mylist' , 0 , - 1 , ' redis ' ) as items;
104
97
105
98
-- Get first 5 items
106
- SELECT redis_lrange(' mylist' , 0 , 4 , ' my_redis ' ) as items;
99
+ SELECT redis_lrange(' mylist' , 0 , 4 , ' redis ' ) as items;
107
100
108
101
-- Push multiple items
109
102
WITH items(value) AS (
110
103
VALUES (' item1' ), (' item2' ), (' item3' )
111
104
)
112
- SELECT redis_lpush(' mylist' , value, ' my_redis ' )
105
+ SELECT redis_lpush(' mylist' , value, ' redis ' )
113
106
FROM items;
114
107
```
115
108
116
109
### Batch Operations
117
110
``` sql
118
111
-- Get multiple keys at once
119
- SELECT redis_mget(' key1,key2,key3' , ' my_redis' ) as values ;
112
+ SELECT redis_mget(' key1,key2,key3' , ' redis' ) as values ;
113
+ -- Returns comma-separated values for all keys
120
114
121
115
-- Scan keys matching a pattern
122
- SELECT redis_scan(' 0' , ' user:*' , 10 , ' my_redis ' ) as result;
116
+ SELECT redis_scan(' 0' , ' user:*' , 10 , ' redis ' ) as result;
123
117
-- Returns: "cursor:key1,key2,key3" where cursor is the next position for scanning
124
118
-- Use the returned cursor for the next scan until cursor is 0
125
119
126
120
-- Scan all keys matching a pattern
127
121
WITH RECURSIVE scan(cursor, keys) AS (
128
122
-- Initial scan
129
- SELECT split_part(redis_scan(' 0' , ' user:*' , 10 , ' my_redis ' ), ' :' , 1 ),
130
- split_part(redis_scan(' 0' , ' user:*' , 10 , ' my_redis ' ), ' :' , 2 )
123
+ SELECT split_part(redis_scan(' 0' , ' user:*' , 10 , ' redis ' ), ' :' , 1 ),
124
+ split_part(redis_scan(' 0' , ' user:*' , 10 , ' redis ' ), ' :' , 2 )
131
125
UNION ALL
132
126
-- Continue scanning until cursor is 0
133
- SELECT split_part(redis_scan(cursor, ' user:*' , 10 , ' my_redis ' ), ' :' , 1 ),
134
- split_part(redis_scan(cursor, ' user:*' , 10 , ' my_redis ' ), ' :' , 2 )
127
+ SELECT split_part(redis_scan(cursor, ' user:*' , 10 , ' redis ' ), ' :' , 1 ),
128
+ split_part(redis_scan(cursor, ' user:*' , 10 , ' redis ' ), ' :' , 2 )
135
129
FROM scan
136
130
WHERE cursor != ' 0'
137
131
)
@@ -156,11 +150,9 @@ Follow the standard DuckDB extension build process:
156
150
make
157
151
```
158
152
159
- ## Dependencies
160
- - Boost.Asio (header-only, installed via vcpkg)
161
-
162
153
## Future Enhancements
163
154
Planned features include:
155
+ - Table functions for scanning Redis keys
164
156
- Additional Redis commands (SADD, SMEMBERS, etc.)
165
157
- Batch operations using Redis pipelines
166
158
- Connection timeout handling
0 commit comments