8000 Json v9 by l-wang · Pull Request #3 · l-wang/postgres · GitHub
[go: up one dir, main page]

Skip to content

Json v9 #3

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Allow wild card member access for jsonb
  • Loading branch information
Nikita Glukhov authored and l-wang committed Feb 27, 2025
commit 26c41cc638cf989bc5e50d9bda78894979873f08
2 changes: 2 additions & 0 deletions src/backend/parser/gram.y
Original file line number Diff line number Diff line change
Expand Up @@ -18968,6 +18968,7 @@ check_func_name(List *names, core_yyscan_t yyscanner)
static List *
check_indirection(List *indirection, core_yyscan_t yyscanner)
{
#if 0
ListCell *l;

foreach(l, indirection)
Expand All @@ -18978,6 +18979,7 @@ check_indirection(List *indirection, core_yyscan_t yyscanner)
parser_yyerror("improper use of \"*\"");
}
}
#endif
return indirection;
}

Expand Down
34 changes: 23 additions & 11 deletions src/backend/parser/parse_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
static Node *transformWholeRowRef(ParseState *pstate,
ParseNamespaceItem *nsitem,
int sublevels_up, int location);
static Node *transformIndirection(ParseState *pstate, A_Indirection *ind);
static Node *transformTypeCast(ParseState *pstate, TypeCast *tc);
static Node *transformCollateClause(ParseState *pstate, CollateClause *c);
static Node *transformJsonObjectConstructor(ParseState *pstate,
Expand Down Expand Up @@ -158,7 +157,7 @@ transformExprRecurse(ParseState *pstate, Node *expr)
break;

case T_A_Indirection:
result = transformIndirection(pstate, (A_Indirection *) expr);
result = transformIndirection(pstate, (A_Indirection *) expr, NULL);
break;

case T_A_ArrayExpr:
Expand Down Expand Up @@ -432,8 +431,9 @@ unknown_attribute(ParseState *pstate, Node *relref, const char *attname,
}
}

static Node *
transformIndirection(ParseState *pstate, A_Indirection *ind)
Node *
transformIndirection(ParseState *pstate, A_Indirection *ind,
bool *trailing_star_expansion)
{
Node *last_srf = pstate->p_last_srf;
Node *result = transformExprRecurse(pstate, ind->arg);
Expand All @@ -454,12 +454,7 @@ transformIndirection(ParseState *pstate, A_Indirection *ind)
if (IsA(n, A_Indices))
subscripts = lappend(subscripts, n);
else if (IsA(n, A_Star))
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("row expansion via \"*\" is not supported here"),
parser_errposition(pstate, location)));
}
subscripts = lappend(subscripts, n);
else
{
Assert(IsA(n, String));
Expand Down Expand Up @@ -491,7 +486,21 @@ transformIndirection(ParseState *pstate, A_Indirection *ind)

n = linitial(subscripts);

if (!IsA(n, String))
if (IsA(n, A_Star))
{
/* Success, if trailing star expansion is allowed */
if (trailing_star_expansion && list_length(subscripts) == 1)
{
*trailing_star_expansion = true;
return result;
}

ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("row expansion via \"*\" is not supported here"),
parser_errposition(pstate, location)));
}
else if (!IsA(n, String))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot subscript type %s because it does not support subscripting",
Expand All @@ -517,6 +526,9 @@ transformIndirection(ParseState *pstate, A_Indirection *ind)
result = newresult;
}

if (trailing_star_expansion)
*trailing_star_expansion = false;

return result;
}

Expand Down
67 changes: 46 additions & 21 deletions src/backend/parser/parse_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate,
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
bool make_target_entry);
static List *ExpandAllTables(ParseState *pstate, int location);
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
static Node *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
bool make_target_entry, ParseExprKind exprKind);
static List *ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem,
int sublevels_up, int location,
Expand Down Expand Up @@ -134,6 +134,7 @@ transformTargetList(ParseState *pstate, List *targetlist,
foreach(o_target, targetlist)
{
ResTarget *res = (ResTarget *) lfirst(o_target);
Node *transformed = NULL;

/*
* Check for "something.*". Depending on the complexity of the
Expand Down Expand Up @@ -162,13 +163,19 @@ transformTargetList(ParseState *pstate, List *targetlist,

if (IsA(llast(ind->indirection), A_Star))
{
/* It is something.*, expand into multiple items */
p_target = list_concat(p_target,
ExpandIndirectionStar(pstate,
ind,
true,
exprKind));
continue;
Node *columns = ExpandIndirectionStar(pstate,
ind,
true,
exprKind);

if (IsA(columns, List))
{
/* It is something.*, expand into multiple items */
p_target = list_concat(p_target, (List *) columns);
continue;
}

transformed = (Node *) columns;
}
}
}
Expand All @@ -180,7 +187,7 @@ transformTargetList(ParseState *pstate, List *targetlist,
p_target = lappend(p_target,
transformTargetEntry(pstate,
res->val,
NULL,
transformed,
exprKind,
res->name,
false));
Expand Down Expand Up @@ -251,10 +258,15 @@ transformExpressionList(ParseState *pstate, List *exprlist,

if (IsA(llast(ind->indirection), A_Star))
{
/* It is something.*, expand into multiple items */
result = list_concat(result,
ExpandIndirectionStar(pstate, ind,
false, exprKind));
Node *cols = ExpandIndirectionStar(pstate, ind,
false, exprKind);

if (!cols || IsA(cols, List))
/* It is something.*, expand into multiple items */
result = list_concat(result, (List *) cols);
else
result = lappend(result, cols);

continue;
}
}
Expand Down Expand Up @@ -1345,22 +1357,30 @@ ExpandAllTables(ParseState *pstate, int location)
* For robustness, we use a separate "make_target_entry" flag to control
* this rather than relying on exprKind.
*/
static List *
static Node *
ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
bool make_target_entry, ParseExprKind exprKind)
{
Node *expr;
ParseExprKind sv_expr_kind;
bool trailing_star_expansion = false;

/* Save and restore identity of expression type we're parsing */
Assert(exprKind != EXPR_KIND_NONE);
sv_expr_kind = pstate->p_expr_kind;
pstate->p_expr_kind = exprKind;

/* Strip off the '*' to create a reference to the rowtype object */
ind = copyObject(ind);
ind->indirection = list_truncate(ind->indirection,
list_length(ind->indirection) - 1);
expr = transformIndirection(pstate, ind, &trailing_star_expansion);

pstate->p_expr_kind = sv_expr_kind;

/* And transform that */
expr = transformExpr(pstate, (Node *) ind, exprKind);
/* '*' was consumed by generic type subscripting */
if (!trailing_star_expansion)
return expr;

/* Expand the rowtype expression into individual fields */
return ExpandRowReference(pstate, expr, make_target_entry);
return (Node *) ExpandRowReference(pstate, expr, make_target_entry);
}

/*
Expand Down Expand Up @@ -1785,13 +1805,18 @@ FigureColnameInternal(Node *node, char **name)
char *fname = NULL;
ListCell *l;

/* find last field name, if any, ignoring "*" and subscripts */
/*
* find last field name, if any, ignoring subscripts, and use
* '?column?' when there's a trailing '*'.
*/
foreach(l, ind->indirection)
{
Node *i = lfirst(l);

if (IsA(i, String))
fname = strVal(i);
else if (IsA(i, A_Star))
fname = "?column?";
}
if (fname)
{
Expand Down
6 changes: 5 additions & 1 deletion src/backend/utils/adt/ruleutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -12926,7 +12926,11 @@ printSubscripts(SubscriptingRef *sbsref, deparse_context *context)
{
Node *up = (Node *) lfirst(uplist_item);

if (IsA(up, String))
if (!up)
{
appendStringInfoString(buf, ".*");
}
else if (IsA(up, String))
{
appendStringInfoChar(buf, '.');
appendStringInfoString(buf, quote_identifier(strVal(up)));
Expand Down
3 changes: 3 additions & 0 deletions src/include/parser/parse_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKin

extern const char *ParseExprKindName(ParseExprKind exprKind);

extern Node *transformIndirection(ParseState *pstate, A_Indirection *ind,
bool *trailing_star_expansion);

#endif /* PARSE_EXPR_H */
Loading
0