Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
d75c36ee
Unverified
Commit
d75c36ee
authored
Mar 21, 2019
by
Salvatore Sanfilippo
Committed by
GitHub
Mar 21, 2019
Browse files
Merge pull request #5390 from oranagra/lookup_key_write
change SORT and SPOP to use lookupKeyWrite rather than lookupKeyRead
parents
9dabbd1a
74717438
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/sort.c
View file @
d75c36ee
...
@@ -58,7 +58,7 @@ redisSortOperation *createSortOperation(int type, robj *pattern) {
...
@@ -58,7 +58,7 @@ redisSortOperation *createSortOperation(int type, robj *pattern) {
*
*
* The returned object will always have its refcount increased by 1
* The returned object will always have its refcount increased by 1
* when it is non-NULL. */
* when it is non-NULL. */
robj
*
lookupKeyByPattern
(
redisDb
*
db
,
robj
*
pattern
,
robj
*
subst
)
{
robj
*
lookupKeyByPattern
(
redisDb
*
db
,
robj
*
pattern
,
robj
*
subst
,
int
writeflag
)
{
char
*
p
,
*
f
,
*
k
;
char
*
p
,
*
f
,
*
k
;
sds
spat
,
ssub
;
sds
spat
,
ssub
;
robj
*
keyobj
,
*
fieldobj
=
NULL
,
*
o
;
robj
*
keyobj
,
*
fieldobj
=
NULL
,
*
o
;
...
@@ -106,7 +106,10 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
...
@@ -106,7 +106,10 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
decrRefCount
(
subst
);
/* Incremented by decodeObject() */
decrRefCount
(
subst
);
/* Incremented by decodeObject() */
/* Lookup substituted key */
/* Lookup substituted key */
o
=
lookupKeyRead
(
db
,
keyobj
);
if
(
!
writeflag
)
o
=
lookupKeyRead
(
db
,
keyobj
);
else
o
=
lookupKeyWrite
(
db
,
keyobj
);
if
(
o
==
NULL
)
goto
noobj
;
if
(
o
==
NULL
)
goto
noobj
;
if
(
fieldobj
)
{
if
(
fieldobj
)
{
...
@@ -198,30 +201,12 @@ void sortCommand(client *c) {
...
@@ -198,30 +201,12 @@ void sortCommand(client *c) {
robj
*
sortval
,
*
sortby
=
NULL
,
*
storekey
=
NULL
;
robj
*
sortval
,
*
sortby
=
NULL
,
*
storekey
=
NULL
;
redisSortObject
*
vector
;
/* Resulting vector to sort */
redisSortObject
*
vector
;
/* Resulting vector to sort */
/* Lookup the key to sort. It must be of the right types */
sortval
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if
(
sortval
&&
sortval
->
type
!=
OBJ_SET
&&
sortval
->
type
!=
OBJ_LIST
&&
sortval
->
type
!=
OBJ_ZSET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
/* Create a list of operations to perform for every sorted element.
/* Create a list of operations to perform for every sorted element.
* Operations can be GET */
* Operations can be GET */
operations
=
listCreate
();
operations
=
listCreate
();
listSetFreeMethod
(
operations
,
zfree
);
listSetFreeMethod
(
operations
,
zfree
);
j
=
2
;
/* options start at argv[2] */
j
=
2
;
/* options start at argv[2] */
/* Now we need to protect sortval incrementing its count, in the future
* SORT may have options able to overwrite/delete keys during the sorting
* and the sorted key itself may get destroyed */
if
(
sortval
)
incrRefCount
(
sortval
);
else
sortval
=
createQuicklistObject
();
/* The SORT command has an SQL-alike syntax, parse it */
/* The SORT command has an SQL-alike syntax, parse it */
while
(
j
<
c
->
argc
)
{
while
(
j
<
c
->
argc
)
{
int
leftargs
=
c
->
argc
-
j
-
1
;
int
leftargs
=
c
->
argc
-
j
-
1
;
...
@@ -280,11 +265,33 @@ void sortCommand(client *c) {
...
@@ -280,11 +265,33 @@ void sortCommand(client *c) {
/* Handle syntax errors set during options parsing. */
/* Handle syntax errors set during options parsing. */
if
(
syntax_error
)
{
if
(
syntax_error
)
{
decrRefCount
(
sortval
);
listRelease
(
operations
);
listRelease
(
operations
);
return
;
return
;
}
}
/* Lookup the key to sort. It must be of the right types */
if
(
storekey
)
sortval
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
else
sortval
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if
(
sortval
&&
sortval
->
type
!=
OBJ_SET
&&
sortval
->
type
!=
OBJ_LIST
&&
sortval
->
type
!=
OBJ_ZSET
)
{
listRelease
(
operations
);
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
/* Now we need to protect sortval incrementing its count, in the future
* SORT may have options able to overwrite/delete keys during the sorting
* and the sorted key itself may get destroyed */
if
(
sortval
)
incrRefCount
(
sortval
);
else
sortval
=
createQuicklistObject
();
/* When sorting a set with no sort specified, we must sort the output
/* When sorting a set with no sort specified, we must sort the output
* so the result is consistent across scripting and replication.
* so the result is consistent across scripting and replication.
*
*
...
@@ -452,7 +459,7 @@ void sortCommand(client *c) {
...
@@ -452,7 +459,7 @@ void sortCommand(client *c) {
robj
*
byval
;
robj
*
byval
;
if
(
sortby
)
{
if
(
sortby
)
{
/* lookup value to sort by */
/* lookup value to sort by */
byval
=
lookupKeyByPattern
(
c
->
db
,
sortby
,
vector
[
j
].
obj
);
byval
=
lookupKeyByPattern
(
c
->
db
,
sortby
,
vector
[
j
].
obj
,
storekey
!=
NULL
);
if
(
!
byval
)
continue
;
if
(
!
byval
)
continue
;
}
else
{
}
else
{
/* use object itself to sort by */
/* use object itself to sort by */
...
@@ -515,7 +522,7 @@ void sortCommand(client *c) {
...
@@ -515,7 +522,7 @@ void sortCommand(client *c) {
while
((
ln
=
listNext
(
&
li
)))
{
while
((
ln
=
listNext
(
&
li
)))
{
redisSortOperation
*
sop
=
ln
->
value
;
redisSortOperation
*
sop
=
ln
->
value
;
robj
*
val
=
lookupKeyByPattern
(
c
->
db
,
sop
->
pattern
,
robj
*
val
=
lookupKeyByPattern
(
c
->
db
,
sop
->
pattern
,
vector
[
j
].
obj
);
vector
[
j
].
obj
,
storekey
!=
NULL
);
if
(
sop
->
type
==
SORT_OP_GET
)
{
if
(
sop
->
type
==
SORT_OP_GET
)
{
if
(
!
val
)
{
if
(
!
val
)
{
...
@@ -545,7 +552,7 @@ void sortCommand(client *c) {
...
@@ -545,7 +552,7 @@ void sortCommand(client *c) {
while
((
ln
=
listNext
(
&
li
)))
{
while
((
ln
=
listNext
(
&
li
)))
{
redisSortOperation
*
sop
=
ln
->
value
;
redisSortOperation
*
sop
=
ln
->
value
;
robj
*
val
=
lookupKeyByPattern
(
c
->
db
,
sop
->
pattern
,
robj
*
val
=
lookupKeyByPattern
(
c
->
db
,
sop
->
pattern
,
vector
[
j
].
obj
);
vector
[
j
].
obj
,
storekey
!=
NULL
);
if
(
sop
->
type
==
SORT_OP_GET
)
{
if
(
sop
->
type
==
SORT_OP_GET
)
{
if
(
!
val
)
val
=
createStringObject
(
""
,
0
);
if
(
!
val
)
val
=
createStringObject
(
""
,
0
);
...
...
src/t_set.c
View file @
d75c36ee
...
@@ -415,7 +415,7 @@ void spopWithCountCommand(client *c) {
...
@@ -415,7 +415,7 @@ void spopWithCountCommand(client *c) {
/* Make sure a key with the name inputted exists, and that it's type is
/* Make sure a key with the name inputted exists, and that it's type is
* indeed a set. Otherwise, return nil */
* indeed a set. Otherwise, return nil */
if
((
set
=
lookupKey
Read
OrReply
(
c
,
c
->
argv
[
1
],
shared
.
null
[
c
->
resp
]))
if
((
set
=
lookupKey
Write
OrReply
(
c
,
c
->
argv
[
1
],
shared
.
null
[
c
->
resp
]))
==
NULL
||
checkType
(
c
,
set
,
OBJ_SET
))
return
;
==
NULL
||
checkType
(
c
,
set
,
OBJ_SET
))
return
;
/* If count is zero, serve an empty multibulk ASAP to avoid special
/* If count is zero, serve an empty multibulk ASAP to avoid special
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment