From ba75f717526cbaa9000b546aac456e43d03aaf53 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 4 Jan 2026 14:16:15 -0500 Subject: [PATCH] Include error location in errors from ComputeIndexAttrs(). Make use of IndexElem's new location field to localize these errors better. Author: jian he Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CACJufxH3OgXF1hrzGAaWyNtye2jHEmk9JbtrtGv-KJK6tsGo5w@mail.gmail.com --- src/backend/bootstrap/bootparse.y | 6 +- src/backend/commands/indexcmds.c | 61 +++++++++++++------ src/backend/commands/tablecmds.c | 9 ++- src/backend/tcop/utility.c | 3 +- src/include/commands/defrem.h | 3 +- src/test/regress/expected/alter_table.out | 4 ++ .../regress/expected/collate.icu.utf8.out | 2 + .../regress/expected/collate.linux.utf8.out | 2 + src/test/regress/expected/collate.out | 2 + .../expected/collate.windows.win1252.out | 2 + .../regress/expected/sqljson_queryfuncs.out | 56 +++++++++++++++++ 11 files changed, 123 insertions(+), 27 deletions(-) diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index d0c3a878526..943ff4733d3 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, diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 023f4706fca..755dc00c86f 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,8 @@ 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': ParseState struct (used only for error reports; pass NULL if + * not available) * '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 +541,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, @@ -933,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, @@ -1517,7 +1522,8 @@ DefineIndex(Oid tableId, SetUserIdAndSecContext(root_save_userid, root_save_sec_context); childAddr = - DefineIndex(childRelid, childStmt, + DefineIndex(NULL, /* original pstate not applicable */ + childRelid, childStmt, InvalidOid, /* no predefined OID */ indexRelationId, /* this is our child */ createdConstraintId, @@ -1866,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, @@ -1951,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, attribute->location))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" does not exist", - attribute->name))); + attribute->name), + parser_errposition(pstate, attribute->location))); } attform = (Form_pg_attribute) GETSTRUCT(atttuple); indexInfo->ii_IndexAttrNumbers[attn] = attform->attnum; @@ -1974,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, attribute->location))); atttype = exprType(expr); attcollation = exprCollation(expr); @@ -2015,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, attribute->location))); } } @@ -2030,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, attribute->location))); 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, attribute->location))); 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, attribute->location))); 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, attribute->location))); opclassOids[attn] = InvalidOid; opclassOptions[attn] = (Datum) 0; @@ -2086,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, attribute->location))); } else { @@ -2094,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, attribute->location))); } collationOids[attn] = attcollation; @@ -2162,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, attribute->location))); /* * Operator must be a member of the right opfamily, too @@ -2175,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, attribute->location))); indexInfo->ii_ExclusionOps[attn] = opid; indexInfo->ii_ExclusionProcs[attn] = get_opcode(opid); @@ -2225,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, attribute->location))); 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, attribute->location))); } /* Set up the per-column opclass options (attoptions field). */ diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ba3190b1660..f976c0e5c7e 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/tcop/utility.c b/src/backend/tcop/utility.c index c73988f7427..34dd6e18df5 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 b16df430cb9..8f4a2d9bbc1 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/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 5e98bbf2425..ac1a7345d0f 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 8023014fe63..1325e123877 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.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out index fbaab7cdf83..c6e84c27b69 100644 --- a/src/test/regress/expected/collate.linux.utf8.out +++ b/src/test/regress/expected/collate.linux.utf8.out @@ -1009,6 +1009,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 bf72908fbd3..25818f09ad2 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/collate.windows.win1252.out b/src/test/regress/expected/collate.windows.win1252.out index 4644f56b31d..2a9e52a6b4a 100644 --- a/src/test/regress/expected/collate.windows.win1252.out +++ b/src/test/regress/expected/collate.windows.win1252.out @@ -845,6 +845,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/sqljson_queryfuncs.out b/src/test/regress/expected/sqljson_queryfuncs.out index 53145f50f18..d1b4b8d99f4 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 $$