diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 9833f52c1bed..063faecadc1f 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -308,7 +308,8 @@ Boot_DeclareIndexStmt: relationId = RangeVarGetRelid(stmt->relation, NoLock, false); - DefineIndex(relationId, + DefineIndex(NULL, + relationId, stmt, $4, InvalidOid, @@ -361,7 +362,8 @@ Boot_DeclareUniqueIndexStmt: relationId = RangeVarGetRelid(stmt->relation, NoLock, false); - DefineIndex(relationId, + DefineIndex(NULL, + relationId, stmt, $5, InvalidOid, @@ -415,6 +417,7 @@ boot_index_param: n->opclass = list_make1(makeString($2)); n->ordering = SORTBY_DEFAULT; n->nulls_ordering = SORTBY_NULLS_DEFAULT; + n->location = -1; $$ = n; } ; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index d9cccb6ac188..832e8bfcbc1d 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -75,7 +75,8 @@ /* non-export function prototypes */ static bool CompareOpclassOptions(const Datum *opts1, const Datum *opts2, int natts); static void CheckPredicate(Expr *predicate); -static void ComputeIndexAttrs(IndexInfo *indexInfo, +static void ComputeIndexAttrs(ParseState *pstate, + IndexInfo *indexInfo, Oid *typeOids, Oid *collationOids, Oid *opclassOids, @@ -248,7 +249,7 @@ CheckIndexCompatible(Oid oldId, opclassIds = palloc_array(Oid, numberOfAttributes); opclassOptions = palloc_array(Datum, numberOfAttributes); coloptions = palloc_array(int16, numberOfAttributes); - ComputeIndexAttrs(indexInfo, + ComputeIndexAttrs(NULL, indexInfo, typeIds, collationIds, opclassIds, opclassOptions, coloptions, attributeList, exclusionOpNames, relationId, @@ -515,6 +516,7 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress) * consider offering one DDL command for catalog setup and a separate DDL * command for steps that run opaque expressions. * + * 'pstate': pointer to ParseState struct for determining error position * 'tableId': the OID of the table relation on which the index is to be * created * 'stmt': IndexStmt describing the properties of the new index. @@ -538,7 +540,8 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress) * Returns the object address of the created index. */ ObjectAddress -DefineIndex(Oid tableId, +DefineIndex(ParseState *pstate, + Oid tableId, IndexStmt *stmt, Oid indexRelationId, Oid parentIndexId, @@ -934,7 +937,8 @@ DefineIndex(Oid tableId, opclassIds = palloc_array(Oid, numberOfAttributes); opclassOptions = palloc_array(Datum, numberOfAttributes); coloptions = palloc_array(int16, numberOfAttributes); - ComputeIndexAttrs(indexInfo, + ComputeIndexAttrs(pstate, + indexInfo, typeIds, collationIds, opclassIds, opclassOptions, coloptions, allIndexParams, stmt->excludeOpNames, tableId, @@ -1518,7 +1522,8 @@ DefineIndex(Oid tableId, SetUserIdAndSecContext(root_save_userid, root_save_sec_context); childAddr = - DefineIndex(childRelid, childStmt, + DefineIndex(NULL, + childRelid, childStmt, InvalidOid, /* no predefined OID */ indexRelationId, /* this is our child */ createdConstraintId, @@ -1867,7 +1872,8 @@ CheckPredicate(Expr *predicate) * InvalidOid, and other ddl_* arguments are undefined. */ static void -ComputeIndexAttrs(IndexInfo *indexInfo, +ComputeIndexAttrs(ParseState *pstate, + IndexInfo *indexInfo, Oid *typeOids, Oid *collationOids, Oid *opclassOids, @@ -1952,12 +1958,14 @@ ComputeIndexAttrs(IndexInfo *indexInfo, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" named in key does not exist", - attribute->name))); + attribute->name)), + parser_errposition(pstate, exprLocation((Node *) attribute))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" does not exist", - attribute->name))); + attribute->name)), + parser_errposition(pstate, exprLocation((Node *) attribute))); } attform = (Form_pg_attribute) GETSTRUCT(atttuple); indexInfo->ii_IndexAttrNumbers[attn] = attform->attnum; @@ -1975,7 +1983,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo, if (attn >= nkeycols) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("expressions are not supported in included columns"))); + errmsg("expressions are not supported in included columns"), + parser_errposition(pstate, exprLocation((Node *) attribute)))); atttype = exprType(expr); attcollation = exprCollation(expr); @@ -2016,7 +2025,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo, if (contain_mutable_functions_after_planning((Expr *) expr)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("functions in index expression must be marked IMMUTABLE"))); + errmsg("functions in index expression must be marked IMMUTABLE"), + parser_errposition(pstate, exprLocation((Node *) attribute)))); } } @@ -2031,19 +2041,23 @@ ComputeIndexAttrs(IndexInfo *indexInfo, if (attribute->collation) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("including column does not support a collation"))); + errmsg("including column does not support a collation"), + parser_errposition(pstate, exprLocation((Node *) attribute)))); if (attribute->opclass) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("including column does not support an operator class"))); + errmsg("including column does not support an operator class"), + parser_errposition(pstate, exprLocation((Node *) attribute)))); if (attribute->ordering != SORTBY_DEFAULT) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("including column does not support ASC/DESC options"))); + errmsg("including column does not support ASC/DESC options"), + parser_errposition(pstate, exprLocation((Node *) attribute)))); if (attribute->nulls_ordering != SORTBY_NULLS_DEFAULT) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("including column does not support NULLS FIRST/LAST options"))); + errmsg("including column does not support NULLS FIRST/LAST options"), + parser_errposition(pstate, exprLocation((Node *) attribute)))); opclassOids[attn] = InvalidOid; opclassOptions[attn] = (Datum) 0; @@ -2087,7 +2101,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo, ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), errmsg("could not determine which collation to use for index expression"), - errhint("Use the COLLATE clause to set the collation explicitly."))); + errhint("Use the COLLATE clause to set the collation explicitly."), + parser_errposition(pstate, exprLocation((Node *) attribute)))); } else { @@ -2095,7 +2110,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo, ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("collations are not supported by type %s", - format_type_be(atttype)))); + format_type_be(atttype)), + parser_errposition(pstate, exprLocation((Node *) attribute)))); } collationOids[attn] = attcollation; @@ -2163,7 +2179,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("operator %s is not commutative", format_operator(opid)), - errdetail("Only commutative operators can be used in exclusion constraints."))); + errdetail("Only commutative operators can be used in exclusion constraints."), + parser_errposition(pstate, exprLocation((Node *) attribute)))); /* * Operator must be a member of the right opfamily, too @@ -2176,7 +2193,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo, errmsg("operator %s is not a member of operator family \"%s\"", format_operator(opid), get_opfamily_name(opfamily, false)), - errdetail("The exclusion operator must be related to the index operator class for the constraint."))); + errdetail("The exclusion operator must be related to the index operator class for the constraint."), + parser_errposition(pstate, exprLocation((Node *) attribute)))); indexInfo->ii_ExclusionOps[attn] = opid; indexInfo->ii_ExclusionProcs[attn] = get_opcode(opid); @@ -2226,12 +2244,14 @@ ComputeIndexAttrs(IndexInfo *indexInfo, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support ASC/DESC options", - accessMethodName))); + accessMethodName), + parser_errposition(pstate, exprLocation((Node *) attribute)))); if (attribute->nulls_ordering != SORTBY_NULLS_DEFAULT) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support NULLS FIRST/LAST options", - accessMethodName))); + accessMethodName), + parser_errposition(pstate, exprLocation((Node *) attribute)))); } /* Set up the per-column opclass options (attoptions field). */ diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 1d9565b09fcd..32be3d3ca75e 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1302,7 +1302,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, idxstmt = generateClonedIndexStmt(NULL, idxRel, attmap, &constraintOid); - DefineIndex(RelationGetRelid(rel), + DefineIndex(NULL, + RelationGetRelid(rel), idxstmt, InvalidOid, RelationGetRelid(idxRel), @@ -9666,7 +9667,8 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, /* suppress notices when rebuilding existing index */ quiet = is_rebuild; - address = DefineIndex(RelationGetRelid(rel), + address = DefineIndex(NULL, + RelationGetRelid(rel), stmt, InvalidOid, /* no predefined OID */ InvalidOid, /* no parent index */ @@ -20770,7 +20772,8 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel) stmt = generateClonedIndexStmt(NULL, idxRel, attmap, &conOid); - DefineIndex(RelationGetRelid(attachrel), stmt, InvalidOid, + DefineIndex(NULL, + RelationGetRelid(attachrel), stmt, InvalidOid, RelationGetRelid(idxRel), conOid, -1, diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 024a2b2fd841..89b7d80c0aaa 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -1726,6 +1726,9 @@ exprLocation(const Node *expr) case T_ColumnDef: loc = ((const ColumnDef *) expr)->location; break; + case T_IndexElem: + loc = ((const IndexElem *) expr)->location; + break; case T_Constraint: loc = ((const Constraint *) expr)->location; break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 28f4e11e30ff..3f407e7d00fd 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -8454,6 +8454,7 @@ index_elem_options: $$->opclassopts = NIL; $$->ordering = $3; $$->nulls_ordering = $4; + $$->location = @1; } | opt_collate any_name reloptions opt_asc_desc opt_nulls_order { @@ -8466,6 +8467,7 @@ index_elem_options: $$->opclassopts = $3; $$->ordering = $4; $$->nulls_ordering = $5; + $$->location = @1; } ; @@ -8478,16 +8480,19 @@ index_elem: ColId index_elem_options { $$ = $2; $$->name = $1; + $$->location = @1; } | func_expr_windowless index_elem_options { $$ = $2; $$->expr = $1; + $$->location = @1; } | '(' a_expr ')' index_elem_options { $$ = $4; $$->expr = $2; + $$->location = @1; } ; diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 57609e2d55c4..34693c8a9e6c 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -3289,20 +3289,20 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer, errmsg("%s is not allowed in ON CONFLICT clause", "ASC/DESC"), parser_errposition(pstate, - exprLocation((Node *) infer)))); + exprLocation((Node *) ielem)))); if (ielem->nulls_ordering != SORTBY_NULLS_DEFAULT) ereport(ERROR, (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), errmsg("%s is not allowed in ON CONFLICT clause", "NULLS FIRST/LAST"), parser_errposition(pstate, - exprLocation((Node *) infer)))); + exprLocation((Node *) ielem)))); if (ielem->opclassopts) ereport(ERROR, errcode(ERRCODE_INVALID_COLUMN_REFERENCE), errmsg("operator class options are not allowed in ON CONFLICT clause"), parser_errposition(pstate, - exprLocation((Node *) infer))); + exprLocation((Node *) ielem))); if (!ielem->expr) { @@ -3342,7 +3342,7 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer, pInfer->infercollid = InvalidOid; else pInfer->infercollid = LookupCollation(pstate, ielem->collation, - exprLocation(pInfer->expr)); + exprLocation((Node *) ielem)); if (!ielem->opclass) pInfer->inferopclass = InvalidOid; diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 2b7b084f2162..535c4060dd4e 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1883,6 +1883,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, int16 opt = source_idx->rd_indoption[keyno]; iparam = makeNode(IndexElem); + iparam->location = -1; if (AttributeNumberIsValid(attnum)) { @@ -1974,6 +1975,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, keyno); iparam = makeNode(IndexElem); + iparam->location = -1; if (AttributeNumberIsValid(attnum)) { @@ -2813,6 +2815,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) iparam->opclassopts = NIL; iparam->ordering = SORTBY_DEFAULT; iparam->nulls_ordering = SORTBY_NULLS_DEFAULT; + iparam->location = -1; index->indexParams = lappend(index->indexParams, iparam); } @@ -2929,6 +2932,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) iparam->collation = NIL; iparam->opclass = NIL; iparam->opclassopts = NIL; + iparam->location = -1; index->indexIncludingParams = lappend(index->indexIncludingParams, iparam); } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index d18a3a60a467..b611eab05503 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1541,7 +1541,8 @@ ProcessUtilitySlow(ParseState *pstate, /* ... and do it */ EventTriggerAlterTableStart(parsetree); address = - DefineIndex(relid, /* OID of heap relation */ + DefineIndex(pstate, + relid, /* OID of heap relation */ stmt, InvalidOid, /* no predefined OID */ InvalidOid, /* no parent index */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index f3432b4b6a15..39afce907075 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -25,7 +25,8 @@ extern void RemoveObjects(DropStmt *stmt); /* commands/indexcmds.c */ -extern ObjectAddress DefineIndex(Oid tableId, +extern ObjectAddress DefineIndex(ParseState *pstate, + Oid tableId, IndexStmt *stmt, Oid indexRelationId, Oid parentIndexId, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index bc7adba4a0fc..b15b937660f5 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -816,6 +816,7 @@ typedef struct IndexElem List *opclassopts; /* opclass-specific options, or NIL */ SortByDir ordering; /* ASC/DESC/default */ SortByNulls nulls_ordering; /* FIRST/LAST/default */ + ParseLoc location; /* token location, or -1 if unknown */ } IndexElem; /* diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 5e98bbf2425a..ac1a7345d0fa 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -1585,8 +1585,12 @@ ERROR: column "........pg.dropped.1........" referenced in foreign key constrai drop table atacc2; create index "testing_idx" on atacc1(a); ERROR: column "a" does not exist +LINE 1: create index "testing_idx" on atacc1(a); + ^ create index "testing_idx" on atacc1("........pg.dropped.1........"); ERROR: column "........pg.dropped.1........" does not exist +LINE 1: create index "testing_idx" on atacc1("........pg.dropped.1..... + ^ -- test create as and select into insert into atacc1 values (21, 22, 23); create table attest1 as select * from atacc1; diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index 8023014fe637..1325e1238777 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -996,6 +996,8 @@ CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")); -- this is d CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")); CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C"); -- fail ERROR: collations are not supported by type integer +LINE 1: CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE ... + ^ CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")); -- fail ERROR: collations are not supported by type integer LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C... diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out index bf72908fbd39..25818f09ad25 100644 --- a/src/test/regress/expected/collate.out +++ b/src/test/regress/expected/collate.out @@ -596,6 +596,8 @@ CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")); -- this CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")); CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX"); -- fail ERROR: collations are not supported by type integer +LINE 1: CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE ... + ^ CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")); -- fail ERROR: collations are not supported by type integer LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "P... diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out index 91fbe91844d2..b0e12962088e 100644 --- a/src/test/regress/expected/insert_conflict.out +++ b/src/test/regress/expected/insert_conflict.out @@ -5,15 +5,15 @@ create table insertconflicttest(key int4, fruit text); -- invalid clauses insert into insertconflicttest values (1) on conflict (key int4_ops (fillfactor=10)) do nothing; ERROR: operator class options are not allowed in ON CONFLICT clause -LINE 1: ...rt into insertconflicttest values (1) on conflict (key int4_... +LINE 1: ...t into insertconflicttest values (1) on conflict (key int4_o... ^ insert into insertconflicttest values (1) on conflict (key asc) do nothing; ERROR: ASC/DESC is not allowed in ON CONFLICT clause -LINE 1: ...rt into insertconflicttest values (1) on conflict (key asc) ... +LINE 1: ...t into insertconflicttest values (1) on conflict (key asc) d... ^ insert into insertconflicttest values (1) on conflict (key nulls last) do nothing; ERROR: NULLS FIRST/LAST is not allowed in ON CONFLICT clause -LINE 1: ...rt into insertconflicttest values (1) on conflict (key nulls... +LINE 1: ...t into insertconflicttest values (1) on conflict (key nulls ... ^ -- These things should work through a view, as well create view insertconflictview as select * from insertconflicttest; diff --git a/src/test/regress/expected/sqljson_queryfuncs.out b/src/test/regress/expected/sqljson_queryfuncs.out index 53145f50f186..d1b4b8d99f47 100644 --- a/src/test/regress/expected/sqljson_queryfuncs.out +++ b/src/test/regress/expected/sqljson_queryfuncs.out @@ -1153,69 +1153,125 @@ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$')); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a[0]')); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time()')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.tim... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date()')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.dat... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time_tz()')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.tim... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp()')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.tim... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp_tz()')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.tim... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time_tz())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time_tz())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.timestamp_tz())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.timestamp_tz())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.datetime("HH:MI TZH"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.datetime("HH:MI TZH"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI TZH"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI TZH"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '12:34'::timetz AS x)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.dat... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '1234'::int AS x)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.dat... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp(2) < $.timestamp(3))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime()')); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@ < $.datetime())')); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime())')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime("HH:MI TZH"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("HH:MI TZH"))')); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI") < $.datetime("YY-MM-DD HH:MI"))')); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("YY-MM-DD HH:MI"))')); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ?... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $x' PASSING '12:34'::timetz AS x)); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $y' PASSING '12:34'::timetz AS x)); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '12:34'::timetz AS x)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.dat... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '1234'::int AS x)); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() ? (@ == $x)' PASSING '12:34'::time AS x)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.dat... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("YY-MM-DD") ? (@ == $x)' PASSING '2020-07-14'::date AS x)); CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, ... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, 0 to $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, ... + ^ CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime("HH:MI") == $x)]' PASSING '12:34'::time AS x)); CREATE INDEX ON test_jsonb_mutability (JSON_VALUE(js, '$' DEFAULT random()::int ON ERROR)); ERROR: functions in index expression must be marked IMMUTABLE +LINE 1: CREATE INDEX ON test_jsonb_mutability (JSON_VALUE(js, '$' DE... + ^ -- DEFAULT expression CREATE OR REPLACE FUNCTION ret_setint() RETURNS SETOF integer AS $$