mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Revert "Common SQL/JSON clauses"
This reverts commit 865fe4d5df
.
This has caused issues with a significant number of buildfarm members
This commit is contained in:
@ -635,14 +635,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
%type <defelt> hash_partbound_elem
|
||||
|
||||
|
||||
%type <node> json_format_clause_opt
|
||||
json_representation
|
||||
json_value_expr
|
||||
json_output_clause_opt
|
||||
|
||||
%type <ival> json_encoding
|
||||
json_encoding_clause_opt
|
||||
|
||||
/*
|
||||
* Non-keyword token types. These are hard-wired into the "flex" lexer.
|
||||
* They must be listed first so that their numeric codes do not depend on
|
||||
@ -694,7 +686,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
EXTENSION EXTERNAL EXTRACT
|
||||
|
||||
FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR
|
||||
FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS
|
||||
FORCE FOREIGN FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS
|
||||
|
||||
GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS
|
||||
|
||||
@ -705,7 +697,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
|
||||
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
|
||||
|
||||
JOIN JSON
|
||||
JOIN
|
||||
|
||||
KEY
|
||||
|
||||
@ -789,7 +781,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
|
||||
/* Precedence: lowest to highest */
|
||||
%nonassoc SET /* see relation_expr_opt_alias */
|
||||
%right FORMAT
|
||||
%left UNION EXCEPT
|
||||
%left INTERSECT
|
||||
%left OR
|
||||
@ -15244,54 +15235,6 @@ opt_asymmetric: ASYMMETRIC
|
||||
| /*EMPTY*/
|
||||
;
|
||||
|
||||
/* SQL/JSON support */
|
||||
|
||||
json_value_expr:
|
||||
a_expr json_format_clause_opt
|
||||
{
|
||||
$$ = (Node *) makeJsonValueExpr((Expr *) $1, $2);
|
||||
}
|
||||
;
|
||||
|
||||
json_format_clause_opt:
|
||||
FORMAT json_representation
|
||||
{
|
||||
$$ = $2;
|
||||
$$.location = @1;
|
||||
}
|
||||
| /* EMPTY */
|
||||
{
|
||||
$$ = (Node *) makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
|
||||
}
|
||||
;
|
||||
|
||||
json_representation:
|
||||
JSON json_encoding_clause_opt
|
||||
{
|
||||
$$ = (Node *) makeJsonFormat(JS_FORMAT_JSON, $2, @1);
|
||||
}
|
||||
/* | other implementation defined JSON representation options (BSON, AVRO etc) */
|
||||
;
|
||||
|
||||
json_encoding_clause_opt:
|
||||
ENCODING json_encoding { $$ = $2; }
|
||||
| /* EMPTY */ { $$ = JS_ENC_DEFAULT; }
|
||||
;
|
||||
|
||||
json_encoding:
|
||||
name { $$ = makeJsonEncoding($1); }
|
||||
;
|
||||
|
||||
json_output_clause_opt:
|
||||
RETURNING Typename json_format_clause_opt
|
||||
{
|
||||
JsonOutput *n = makeNode(JsonOutput);
|
||||
n->typeName = $2;
|
||||
n->returning.format = $3;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| /* EMPTY */ { $$ = NULL; }
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@ -15833,7 +15776,6 @@ unreserved_keyword:
|
||||
| FIRST_P
|
||||
| FOLLOWING
|
||||
| FORCE
|
||||
| FORMAT
|
||||
| FORWARD
|
||||
| FUNCTION
|
||||
| FUNCTIONS
|
||||
@ -15865,7 +15807,6 @@ unreserved_keyword:
|
||||
| INSTEAD
|
||||
| INVOKER
|
||||
| ISOLATION
|
||||
| JSON
|
||||
| KEY
|
||||
| LABEL
|
||||
| LANGUAGE
|
||||
@ -16382,7 +16323,6 @@ bare_label_keyword:
|
||||
| FOLLOWING
|
||||
| FORCE
|
||||
| FOREIGN
|
||||
| FORMAT
|
||||
| FORWARD
|
||||
| FREEZE
|
||||
| FULL
|
||||
@ -16427,7 +16367,6 @@ bare_label_keyword:
|
||||
| IS
|
||||
| ISOLATION
|
||||
| JOIN
|
||||
| JSON
|
||||
| KEY
|
||||
| LABEL
|
||||
| LANGUAGE
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "parser/parse_type.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/date.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/timestamp.h"
|
||||
#include "utils/xml.h"
|
||||
@ -3100,183 +3099,3 @@ ParseExprKindName(ParseExprKind exprKind)
|
||||
}
|
||||
return "unrecognized expression kind";
|
||||
}
|
||||
|
||||
/*
|
||||
* Make string Const node from JSON encoding name.
|
||||
*
|
||||
* UTF8 is default encoding.
|
||||
*/
|
||||
static Const *
|
||||
getJsonEncodingConst(JsonFormat *format)
|
||||
{
|
||||
JsonEncoding encoding;
|
||||
const char *enc;
|
||||
Name encname = palloc(sizeof(NameData));
|
||||
|
||||
if (!format ||
|
||||
format->format_type == JS_FORMAT_DEFAULT ||
|
||||
format->encoding == JS_ENC_DEFAULT)
|
||||
encoding = JS_ENC_UTF8;
|
||||
else
|
||||
encoding = format->encoding;
|
||||
|
||||
switch (encoding)
|
||||
{
|
||||
case JS_ENC_UTF16:
|
||||
enc = "UTF16";
|
||||
break;
|
||||
case JS_ENC_UTF32:
|
||||
enc = "UTF32";
|
||||
break;
|
||||
case JS_ENC_UTF8:
|
||||
enc = "UTF8";
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "invalid JSON encoding: %d", encoding);
|
||||
break;
|
||||
}
|
||||
|
||||
namestrcpy(encname, enc);
|
||||
|
||||
return makeConst(NAMEOID, -1, InvalidOid, NAMEDATALEN,
|
||||
NameGetDatum(encname), false, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make bytea => text conversion using specified JSON format encoding.
|
||||
*/
|
||||
static Node *
|
||||
makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
|
||||
{
|
||||
Const *encoding = getJsonEncodingConst(format);
|
||||
FuncExpr *fexpr = makeFuncExpr(F_CONVERT_FROM, TEXTOID,
|
||||
list_make2(expr, encoding),
|
||||
InvalidOid, InvalidOid,
|
||||
COERCE_EXPLICIT_CALL);
|
||||
|
||||
fexpr->location = location;
|
||||
|
||||
return (Node *) fexpr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make CaseTestExpr node.
|
||||
*/
|
||||
static Node *
|
||||
makeCaseTestExpr(Node *expr)
|
||||
{
|
||||
CaseTestExpr *placeholder = makeNode(CaseTestExpr);
|
||||
|
||||
placeholder->typeId = exprType(expr);
|
||||
placeholder->typeMod = exprTypmod(expr);
|
||||
placeholder->collation = exprCollation(expr);
|
||||
|
||||
return (Node *) placeholder;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transform JSON value expression using specified input JSON format or
|
||||
* default format otherwise.
|
||||
*/
|
||||
static Node *
|
||||
transformJsonValueExpr(ParseState *pstate, JsonValueExpr *ve,
|
||||
JsonFormatType default_format)
|
||||
{
|
||||
Node *expr = transformExprRecurse(pstate, (Node *) ve->raw_expr);
|
||||
Node *rawexpr;
|
||||
JsonFormatType format;
|
||||
Oid exprtype;
|
||||
int location;
|
||||
char typcategory;
|
||||
bool typispreferred;
|
||||
|
||||
if (exprType(expr) == UNKNOWNOID)
|
||||
expr = coerce_to_specific_type(pstate, expr, TEXTOID, "JSON_VALUE_EXPR");
|
||||
|
||||
rawexpr = expr;
|
||||
exprtype = exprType(expr);
|
||||
location = exprLocation(expr);
|
||||
|
||||
get_type_category_preferred(exprtype, &typcategory, &typispreferred);
|
||||
|
||||
if (ve->format->format_type != JS_FORMAT_DEFAULT)
|
||||
{
|
||||
if (ve->format->encoding != JS_ENC_DEFAULT && exprtype != BYTEAOID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("JSON ENCODING clause is only allowed for bytea input type"),
|
||||
parser_errposition(pstate, ve->format->location)));
|
||||
|
||||
if (exprtype == JSONOID || exprtype == JSONBOID)
|
||||
{
|
||||
format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
|
||||
ereport(WARNING,
|
||||
(errmsg("FORMAT JSON has no effect for json and jsonb types"),
|
||||
parser_errposition(pstate, ve->format->location)));
|
||||
}
|
||||
else
|
||||
format = ve->format->format_type;
|
||||
}
|
||||
else if (exprtype == JSONOID || exprtype == JSONBOID)
|
||||
format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
|
||||
else
|
||||
format = default_format;
|
||||
|
||||
if (format != JS_FORMAT_DEFAULT)
|
||||
{
|
||||
Oid targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
|
||||
Node *orig = makeCaseTestExpr(expr);
|
||||
Node *coerced;
|
||||
|
||||
expr = orig;
|
||||
|
||||
if (exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg(ve->format->format_type == JS_FORMAT_DEFAULT ?
|
||||
"cannot use non-string types with implicit FORMAT JSON clause" :
|
||||
"cannot use non-string types with explicit FORMAT JSON clause"),
|
||||
parser_errposition(pstate, ve->format->location >= 0 ?
|
||||
ve->format->location : location)));
|
||||
|
||||
/* Convert encoded JSON text from bytea. */
|
||||
if (format == JS_FORMAT_JSON && exprtype == BYTEAOID)
|
||||
{
|
||||
expr = makeJsonByteaToTextConversion(expr, ve->format, location);
|
||||
exprtype = TEXTOID;
|
||||
}
|
||||
|
||||
/* Try to coerce to the target type. */
|
||||
coerced = coerce_to_target_type(pstate, expr, exprtype,
|
||||
targettype, -1,
|
||||
COERCION_EXPLICIT,
|
||||
COERCE_EXPLICIT_CAST,
|
||||
location);
|
||||
|
||||
if (!coerced)
|
||||
{
|
||||
/* If coercion failed, use to_json()/to_jsonb() functions. */
|
||||
Oid fnoid = targettype == JSONOID ? F_TO_JSON : F_TO_JSONB;
|
||||
FuncExpr *fexpr = makeFuncExpr(fnoid, targettype,
|
||||
list_make1(expr),
|
||||
InvalidOid, InvalidOid,
|
||||
COERCE_EXPLICIT_CALL);
|
||||
fexpr->location = location;
|
||||
|
||||
coerced = (Node *) fexpr;
|
||||
}
|
||||
|
||||
if (coerced == orig)
|
||||
expr = rawexpr;
|
||||
else
|
||||
{
|
||||
ve = copyObject(ve);
|
||||
ve->raw_expr = (Expr *) rawexpr;
|
||||
ve->formatted_expr = (Expr *) coerced;
|
||||
|
||||
expr = (Node *) ve;
|
||||
}
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
Reference in New Issue
Block a user