Skip to content

Commit

Permalink
fix: Handle None-array type JSONB as Empty Array in Predicate functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
emotionbug committed Dec 19, 2022
1 parent 9f1178b commit 32fc0cf
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/backend/executor/execExpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4218,6 +4218,10 @@ ExecInitCypherListComp(ExprEvalStep *scratch, CypherListCompExpr *listcompexpr,
init_step.d.cypherlistcomp_iter.array_typid =
(Oid *) palloc(sizeof(Oid));

init_step.d.cypherlistcomp_iter.is_null_list_or_array =
(bool *) palloc(sizeof(bool));
*init_step.d.cypherlistcomp_iter.is_null_list_or_array = false;

ExprEvalPushStep(state, &init_step);

elem_resvalue = (Datum *) palloc(sizeof(Datum));
Expand Down Expand Up @@ -4248,6 +4252,8 @@ ExecInitCypherListComp(ExprEvalStep *scratch, CypherListCompExpr *listcompexpr,
init_step.d.cypherlistcomp_iter.array_size;
next_step.d.cypherlistcomp_iter.array_typid =
init_step.d.cypherlistcomp_iter.array_typid;
next_step.d.cypherlistcomp_iter.is_null_list_or_array =
init_step.d.cypherlistcomp_iter.is_null_list_or_array;

ExprEvalPushStep(state, &next_step);
next_stepno = state->steps_len - 1;
Expand Down
15 changes: 10 additions & 5 deletions src/backend/executor/execExprInterp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5287,11 +5287,9 @@ ExecEvalCypherListCompIterInit(ExprState *state, ExprEvalStep *op)

listjb = DatumGetJsonbP(*op->d.cypherlistcomp_iter.listvalue);
if (!JB_ROOT_IS_ARRAY(listjb) || JB_ROOT_IS_SCALAR(listjb))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("list is expected but %s",
JsonbToCString(NULL, &listjb->root,
VARSIZE(listjb)))));
{
*op->d.cypherlistcomp_iter.is_null_list_or_array = true;
}

ji = op->d.cypherlistcomp_iter.listiter;
*ji = JsonbIteratorInit(&listjb->root);
Expand Down Expand Up @@ -5323,6 +5321,13 @@ ExecEvalCypherListCompIterInitNext(ExprState *state, ExprEvalStep *op)
JsonbValue jv;
JsonbIteratorToken jt;

if (*op->d.cypherlistcomp_iter.is_null_list_or_array)
{
*op->resvalue = (Datum) 0;
*op->resnull = true;
return;
}

ji = op->d.cypherlistcomp_iter.listiter;
jt = JsonbIteratorNext(ji, &jv, true);
if (jt == WJB_ELEM)
Expand Down
1 change: 1 addition & 0 deletions src/include/executor/execExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ typedef struct ExprEvalStep
bool *typbyval;
char *typalign;
bool is_array_type;
bool *is_null_list_or_array;
} cypherlistcomp_iter;

struct
Expand Down
36 changes: 36 additions & 0 deletions src/test/regress/sql/cypher_dml2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@ create (a:person {name: 'Alice', age: 51, eyes: 'brown'}),
(d)-[:knows]->(e),
(d)-[:married]->(f);

-- all(..)
MATCH p = (a)-[*1..3]->(b)
WHERE
a.name = 'Alice'
AND b.name = 'Daniel'
AND all(x IN nodes(p) WHERE x.age > 30)
RETURN [x in nodes(p) | x.age];

-- any(..)
MATCH (n)
WHERE any(color IN n.liked_colors WHERE color = 'yellow')
RETURN n ;

-- exists(..)
MATCH (n)
WHERE n.name IS NOT NULL
RETURN
n.name AS name,
exists((n)-[:MARRIED]->()) AS is_married;

-- isEmpty(..)
-- List
MATCH (n)
Expand All @@ -87,6 +107,22 @@ MATCH (n)
WHERE isEmpty(n.eyes)
RETURN n.age AS age ;

-- none(..)
MATCH p = (n)-[*1..3]->(b)
WHERE
n.name = 'Alice'
AND none(x IN nodes(p) WHERE x.age = 25)
RETURN p ;

-- single(..)
MATCH p = (n)-->(b)
WHERE
n.name = 'Alice'
AND single(var IN nodes(p) WHERE var.eyes = 'blue')
RETURN p ;

MATCH (n) DETACH DELETE n;

-- Trigger
CREATE TEMPORARY TABLE _trigger_history(
id graphid,
Expand Down

0 comments on commit 32fc0cf

Please sign in to comment.