diff --git a/Rakefile b/Rakefile index 328f8c19..b95a35b7 100644 --- a/Rakefile +++ b/Rakefile @@ -5,8 +5,8 @@ require 'rspec/core/rake_task' require 'rubocop/rake_task' require 'open-uri' -LIB_PG_QUERY_TAG = '13-2.1.0'.freeze -LIB_PG_QUERY_SHA256SUM = 'a01329ae5bac19b10b8ddf8012bd663a20f85f180d6d7b900c1a1ca8444d19a5'.freeze +LIB_PG_QUERY_TAG = '13-2.2.0'.freeze +LIB_PG_QUERY_SHA256SUM = '07916be1a2b780dee6feed936aaa04ccee2a3afde8570a6920c3a839c87539c6'.freeze Rake::ExtensionTask.new 'pg_query' do |ext| ext.lib_dir = 'lib/pg_query' diff --git a/ext/pg_query/include/access/twophase.h b/ext/pg_query/include/access/twophase.h index 2ca71c34..9e2125f5 100644 --- a/ext/pg_query/include/access/twophase.h +++ b/ext/pg_query/include/access/twophase.h @@ -34,6 +34,8 @@ extern void TwoPhaseShmemInit(void); extern void AtAbort_Twophase(void); extern void PostPrepare_Twophase(void); +extern TransactionId TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid, + bool *have_more); extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid, bool lock_held); extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held); diff --git a/ext/pg_query/include/access/xact.h b/ext/pg_query/include/access/xact.h index 3c66119d..f00fe4eb 100644 --- a/ext/pg_query/include/access/xact.h +++ b/ext/pg_query/include/access/xact.h @@ -103,6 +103,12 @@ extern int MyXactFlags; */ #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1) +/* + * XACT_FLAGS_NEEDIMMEDIATECOMMIT - records whether the top level statement + * is one that requires immediate commit, such as CREATE DATABASE. + */ +#define XACT_FLAGS_NEEDIMMEDIATECOMMIT (1U << 2) + /* * start- and end-of-transaction callbacks for dynamically loaded modules */ diff --git a/ext/pg_query/include/access/xlog_internal.h b/ext/pg_query/include/access/xlog_internal.h index 88f3d767..51def851 100644 --- a/ext/pg_query/include/access/xlog_internal.h +++ b/ext/pg_query/include/access/xlog_internal.h @@ -79,8 +79,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; #define XLP_LONG_HEADER 0x0002 /* This flag indicates backup blocks starting in this page are optional */ #define XLP_BKP_REMOVABLE 0x0004 +/* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */ +#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008 /* All defined flag bits in xlp_info (used for validity checking of header) */ -#define XLP_ALL_FLAGS 0x0007 +#define XLP_ALL_FLAGS 0x000F #define XLogPageHeaderSize(hdr) \ (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) @@ -252,6 +254,13 @@ typedef struct xl_restore_point char rp_name[MAXFNAMELEN]; } xl_restore_point; +/* Overwrite of prior contrecord */ +typedef struct xl_overwrite_contrecord +{ + XLogRecPtr overwritten_lsn; + TimestampTz overwrite_time; +} xl_overwrite_contrecord; + /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ typedef struct xl_end_of_recovery { diff --git a/ext/pg_query/include/access/xlogreader.h b/ext/pg_query/include/access/xlogreader.h index b0f2a6ed..89ed9de2 100644 --- a/ext/pg_query/include/access/xlogreader.h +++ b/ext/pg_query/include/access/xlogreader.h @@ -250,6 +250,16 @@ struct XLogReaderState /* Buffer to hold error message */ char *errormsg_buf; + + /* + * Set at the end of recovery: the start point of a partial record at the + * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start + * location of its first contrecord that went missing. + */ + XLogRecPtr abortedRecPtr; + XLogRecPtr missingContrecPtr; + /* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */ + XLogRecPtr overwrittenRecPtr; }; /* Get a new XLogReader */ diff --git a/ext/pg_query/include/catalog/dependency.h b/ext/pg_query/include/catalog/dependency.h index 7fe3fb7e..be235ed6 100644 --- a/ext/pg_query/include/catalog/dependency.h +++ b/ext/pg_query/include/catalog/dependency.h @@ -201,6 +201,8 @@ extern void recordMultipleDependencies(const ObjectAddress *depender, extern void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace); +extern void checkMembershipInCurrentExtension(const ObjectAddress *object); + extern long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps); diff --git a/ext/pg_query/include/catalog/pg_class.h b/ext/pg_query/include/catalog/pg_class.h index 78b33b2a..e675520f 100644 --- a/ext/pg_query/include/catalog/pg_class.h +++ b/ext/pg_query/include/catalog/pg_class.h @@ -178,7 +178,7 @@ typedef FormData_pg_class *Form_pg_class; /* * an explicitly chosen candidate key's columns are used as replica identity. * Note this will still be set if the index has been dropped; in that case it - * has the same meaning as 'd'. + * has the same meaning as 'n'. */ #define REPLICA_IDENTITY_INDEX 'i' diff --git a/ext/pg_query/include/catalog/pg_class_d.h b/ext/pg_query/include/catalog/pg_class_d.h index 7f9a66c8..557e209d 100644 --- a/ext/pg_query/include/catalog/pg_class_d.h +++ b/ext/pg_query/include/catalog/pg_class_d.h @@ -82,7 +82,7 @@ /* * an explicitly chosen candidate key's columns are used as replica identity. * Note this will still be set if the index has been dropped; in that case it - * has the same meaning as 'd'. + * has the same meaning as 'n'. */ #define REPLICA_IDENTITY_INDEX 'i' diff --git a/ext/pg_query/include/catalog/pg_control.h b/ext/pg_query/include/catalog/pg_control.h index de5670e5..92013301 100644 --- a/ext/pg_query/include/catalog/pg_control.h +++ b/ext/pg_query/include/catalog/pg_control.h @@ -76,6 +76,8 @@ typedef struct CheckPoint #define XLOG_END_OF_RECOVERY 0x90 #define XLOG_FPI_FOR_HINT 0xA0 #define XLOG_FPI 0xB0 +/* 0xC0 is used in Postgres 9.5-11 */ +#define XLOG_OVERWRITE_CONTRECORD 0xD0 /* diff --git a/ext/pg_query/include/catalog/pg_operator.h b/ext/pg_query/include/catalog/pg_operator.h index 1daa2638..5aaa02e8 100644 --- a/ext/pg_query/include/catalog/pg_operator.h +++ b/ext/pg_query/include/catalog/pg_operator.h @@ -95,7 +95,9 @@ extern ObjectAddress OperatorCreate(const char *operatorName, bool canMerge, bool canHash); -extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, bool isUpdate); +extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, + bool makeExtensionDep, + bool isUpdate); extern void OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete); diff --git a/ext/pg_query/include/catalog/pg_publication.h b/ext/pg_query/include/catalog/pg_publication.h index 5955ba0c..c876085a 100644 --- a/ext/pg_query/include/catalog/pg_publication.h +++ b/ext/pg_query/include/catalog/pg_publication.h @@ -107,6 +107,9 @@ extern List *GetAllTablesPublicationRelations(bool pubviaroot); extern bool is_publishable_relation(Relation rel); extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel, bool if_not_exists); +extern List *GetPubPartitionOptionRelations(List *result, + PublicationPartOpt pub_partopt, + Oid relid); extern Oid get_publication_oid(const char *pubname, bool missing_ok); extern char *get_publication_name(Oid pubid, bool missing_ok); diff --git a/ext/pg_query/include/catalog/pg_type.h b/ext/pg_query/include/catalog/pg_type.h index 7b375626..ebde49da 100644 --- a/ext/pg_query/include/catalog/pg_type.h +++ b/ext/pg_query/include/catalog/pg_type.h @@ -359,6 +359,7 @@ extern void GenerateTypeDependencies(HeapTuple typeTuple, * rowtypes */ bool isImplicitArray, bool isDependentType, + bool makeExtensionDep, bool rebuild); extern void RenameTypeInternal(Oid typeOid, const char *newTypeName, diff --git a/ext/pg_query/include/commands/async.h b/ext/pg_query/include/commands/async.h index 4c35394f..a54bebf2 100644 --- a/ext/pg_query/include/commands/async.h +++ b/ext/pg_query/include/commands/async.h @@ -49,6 +49,6 @@ extern void ProcessCompletedNotifies(void); extern void HandleNotifyInterrupt(void); /* process interrupts */ -extern void ProcessNotifyInterrupt(void); +extern void ProcessNotifyInterrupt(bool flush); #endif /* ASYNC_H */ diff --git a/ext/pg_query/include/commands/tablespace.h b/ext/pg_query/include/commands/tablespace.h index fd1b28fc..8d142c05 100644 --- a/ext/pg_query/include/commands/tablespace.h +++ b/ext/pg_query/include/commands/tablespace.h @@ -19,6 +19,8 @@ #include "lib/stringinfo.h" #include "nodes/parsenodes.h" +extern bool allow_in_place_tablespaces; + /* XLOG stuff */ #define XLOG_TBLSPC_CREATE 0x00 #define XLOG_TBLSPC_DROP 0x10 diff --git a/ext/pg_query/include/commands/trigger.h b/ext/pg_query/include/commands/trigger.h index a40ddf5d..b76d91af 100644 --- a/ext/pg_query/include/commands/trigger.h +++ b/ext/pg_query/include/commands/trigger.h @@ -162,12 +162,20 @@ extern ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, Oid funcoid, Oid parentTriggerOid, Node *whenClause, bool isInternal, bool in_partition); +extern ObjectAddress CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, + Oid relOid, Oid refRelOid, Oid constraintOid, + Oid indexOid, Oid funcoid, Oid parentTriggerOid, + Node *whenClause, bool isInternal, bool in_partition, + char trigger_fires_when); extern void RemoveTriggerById(Oid trigOid); extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok); extern ObjectAddress renametrig(RenameStmt *stmt); +extern void EnableDisableTriggerNew(Relation rel, const char *tgname, + char fires_when, bool skip_system, bool recurse, + LOCKMODE lockmode); extern void EnableDisableTrigger(Relation rel, const char *tgname, char fires_when, bool skip_system, LOCKMODE lockmode); diff --git a/ext/pg_query/include/lib/simplehash.h b/ext/pg_query/include/lib/simplehash.h index 90dfa8a6..e70d5a37 100644 --- a/ext/pg_query/include/lib/simplehash.h +++ b/ext/pg_query/include/lib/simplehash.h @@ -55,6 +55,11 @@ * presence is relevant to determine whether a lookup needs to continue * looking or is done - buckets following a deleted element are shifted * backwards, unless they're empty or already at their optimal position. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/lib/simplehash.h */ #include "port/pg_bitutils.h" @@ -156,7 +161,7 @@ SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements, #endif SH_SCOPE void SH_DESTROY(SH_TYPE * tb); SH_SCOPE void SH_RESET(SH_TYPE * tb); -SH_SCOPE void SH_GROW(SH_TYPE * tb, uint32 newsize); +SH_SCOPE void SH_GROW(SH_TYPE * tb, uint64 newsize); SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found); SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found); @@ -218,7 +223,8 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb); #define SIMPLEHASH_H #ifdef FRONTEND -#define sh_error(...) pg_log_error(__VA_ARGS__) +#define sh_error(...) \ + do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0) #define sh_log(...) pg_log_info(__VA_ARGS__) #else #define sh_error(...) elog(ERROR, __VA_ARGS__) @@ -232,7 +238,7 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb); * the hashtable. */ static inline void -SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize) +SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint64 newsize) { uint64 size; @@ -247,16 +253,12 @@ SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize) * Verify that allocation of ->data is possible on this platform, without * overflowing Size. */ - if ((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2) + if (unlikely((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2)) sh_error("hash table too large"); /* now set size */ tb->size = size; - - if (tb->size == SH_MAX_SIZE) - tb->sizemask = 0; - else - tb->sizemask = tb->size - 1; + tb->sizemask = (uint32) (size - 1); /* * Compute the next threshold at which we need to grow the hash table @@ -406,7 +408,7 @@ SH_RESET(SH_TYPE * tb) * performance-wise, when known at some point. */ SH_SCOPE void -SH_GROW(SH_TYPE * tb, uint32 newsize) +SH_GROW(SH_TYPE * tb, uint64 newsize) { uint64 oldsize = tb->size; SH_ELEMENT_TYPE *olddata = tb->data; @@ -536,10 +538,8 @@ SH_INSERT_HASH_INTERNAL(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found) */ if (unlikely(tb->members >= tb->grow_threshold)) { - if (tb->size == SH_MAX_SIZE) - { + if (unlikely(tb->size == SH_MAX_SIZE)) sh_error("hash table size exceeded"); - } /* * When optimizing, it can be very useful to print these out. diff --git a/ext/pg_query/include/libpq/libpq.h b/ext/pg_query/include/libpq/libpq.h index b1152475..54c5fa77 100644 --- a/ext/pg_query/include/libpq/libpq.h +++ b/ext/pg_query/include/libpq/libpq.h @@ -72,6 +72,7 @@ extern int pq_getmessage(StringInfo s, int maxlen); extern int pq_getbyte(void); extern int pq_peekbyte(void); extern int pq_getbyte_if_available(unsigned char *c); +extern bool pq_buffer_has_data(void); extern int pq_putbytes(const char *s, size_t len); /* diff --git a/ext/pg_query/include/mb/pg_wchar.h b/ext/pg_query/include/mb/pg_wchar.h index 494aefc7..b43454b6 100644 --- a/ext/pg_query/include/mb/pg_wchar.h +++ b/ext/pg_query/include/mb/pg_wchar.h @@ -553,6 +553,7 @@ extern int pg_valid_server_encoding_id(int encoding); * earlier in this file are also available from libpgcommon. */ extern int pg_encoding_mblen(int encoding, const char *mbstr); +extern int pg_encoding_mblen_bounded(int encoding, const char *mbstr); extern int pg_encoding_dsplen(int encoding, const char *mbstr); extern int pg_encoding_verifymb(int encoding, const char *mbstr, int len); extern int pg_encoding_max_length(int encoding); diff --git a/ext/pg_query/include/miscadmin.h b/ext/pg_query/include/miscadmin.h index a3697fc0..7f1bb340 100644 --- a/ext/pg_query/include/miscadmin.h +++ b/ext/pg_query/include/miscadmin.h @@ -57,6 +57,15 @@ * allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and * RESUME_CANCEL_INTERRUPTS(). * + * Note that ProcessInterrupts() has also acquired a number of tasks that + * do not necessarily cause a query-cancel-or-die response. Hence, it's + * possible that it will just clear InterruptPending and return. + * + * INTERRUPTS_PENDING_CONDITION() can be checked to see whether an + * interrupt needs to be serviced, without trying to do so immediately. + * Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(), + * which tells whether ProcessInterrupts is sure to clear the interrupt. + * * Special mechanisms are used to let an interrupt be accepted when we are * waiting for a lock or when we are waiting for command input (but, of * course, only if the interrupt holdoff counter is zero). See the @@ -94,24 +103,27 @@ extern PGDLLIMPORT __thread volatile uint32 CritSectionCount; /* in tcop/postgres.c */ extern void ProcessInterrupts(void); +/* Test whether an interrupt is pending */ #ifndef WIN32 +#define INTERRUPTS_PENDING_CONDITION() \ + (unlikely(InterruptPending)) +#else +#define INTERRUPTS_PENDING_CONDITION() \ + (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \ + unlikely(InterruptPending)) +#endif +/* Service interrupt, if one is pending and it's safe to service it now */ #define CHECK_FOR_INTERRUPTS() \ do { \ - if (unlikely(InterruptPending)) \ - ProcessInterrupts(); \ -} while(0) -#else /* WIN32 */ - -#define CHECK_FOR_INTERRUPTS() \ -do { \ - if (unlikely(UNBLOCKED_SIGNAL_QUEUE())) \ - pgwin32_dispatch_queued_signals(); \ - if (unlikely(InterruptPending)) \ + if (INTERRUPTS_PENDING_CONDITION()) \ ProcessInterrupts(); \ } while(0) -#endif /* WIN32 */ +/* Is ProcessInterrupts() guaranteed to clear InterruptPending? */ +#define INTERRUPTS_CAN_BE_PROCESSED() \ + (InterruptHoldoffCount == 0 && CritSectionCount == 0 && \ + QueryCancelHoldoffCount == 0) #define HOLD_INTERRUPTS() (InterruptHoldoffCount++) @@ -471,6 +483,7 @@ extern bool BackupInProgress(void); extern void CancelBackup(void); /* in executor/nodeHash.c */ +extern size_t get_hash_memory_limit(void); extern int get_hash_mem(void); #endif /* MISCADMIN_H */ diff --git a/ext/pg_query/include/nodes/execnodes.h b/ext/pg_query/include/nodes/execnodes.h index 3c6fecd2..a9a45f56 100644 --- a/ext/pg_query/include/nodes/execnodes.h +++ b/ext/pg_query/include/nodes/execnodes.h @@ -1454,7 +1454,7 @@ typedef struct IndexScanState /* ---------------- * IndexOnlyScanState information * - * indexqual execution state for indexqual expressions + * recheckqual execution state for recheckqual expressions * ScanKeys Skey structures for index quals * NumScanKeys number of ScanKeys * OrderByKeys Skey structures for index ordering operators @@ -1473,7 +1473,7 @@ typedef struct IndexScanState typedef struct IndexOnlyScanState { ScanState ss; /* its first field is NodeTag */ - ExprState *indexqual; + ExprState *recheckqual; struct ScanKeyData *ioss_ScanKeys; int ioss_NumScanKeys; struct ScanKeyData *ioss_OrderByKeys; diff --git a/ext/pg_query/include/nodes/parsenodes.h b/ext/pg_query/include/nodes/parsenodes.h index 557074c2..94384878 100644 --- a/ext/pg_query/include/nodes/parsenodes.h +++ b/ext/pg_query/include/nodes/parsenodes.h @@ -915,10 +915,10 @@ typedef struct PartitionCmd * inFromCl marks those range variables that are listed in the FROM clause. * It's false for RTEs that are added to a query behind the scenes, such * as the NEW and OLD variables for a rule, or the subqueries of a UNION. - * This flag is not used anymore during parsing, since the parser now uses - * a separate "namespace" data structure to control visibility, but it is - * needed by ruleutils.c to determine whether RTEs should be shown in - * decompiled queries. + * This flag is not used during parsing (except in transformLockingClause, + * q.v.); the parser now uses a separate "namespace" data structure to + * control visibility. But it is needed by ruleutils.c to determine + * whether RTEs should be shown in decompiled queries. * * requiredPerms and checkAsUser specify run-time access permissions * checks to be performed at query startup. The user must have *all* @@ -1876,6 +1876,7 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ * constraint, or parent table */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ bool missing_ok; /* skip error if missing? */ + bool recurse; /* exec-time recursion */ } AlterTableCmd; diff --git a/ext/pg_query/include/nodes/pathnodes.h b/ext/pg_query/include/nodes/pathnodes.h index 69150e46..5ebf0709 100644 --- a/ext/pg_query/include/nodes/pathnodes.h +++ b/ext/pg_query/include/nodes/pathnodes.h @@ -258,7 +258,8 @@ struct PlannerInfo List *init_plans; /* init SubPlans for query */ - List *cte_plan_ids; /* per-CTE-item list of subplan IDs */ + List *cte_plan_ids; /* per-CTE-item list of subplan IDs (or -1 if + * no subplan was made for that CTE) */ List *multiexpr_params; /* List of Lists of Params for MULTIEXPR * subquery outputs */ diff --git a/ext/pg_query/include/nodes/pg_list.h b/ext/pg_query/include/nodes/pg_list.h index 54447bb5..b3059681 100644 --- a/ext/pg_query/include/nodes/pg_list.h +++ b/ext/pg_query/include/nodes/pg_list.h @@ -560,6 +560,7 @@ extern List *list_delete_int(List *list, int datum); extern List *list_delete_oid(List *list, Oid datum); extern List *list_delete_first(List *list); extern List *list_delete_last(List *list); +extern List *list_delete_first_n(List *list, int n); extern List *list_delete_nth_cell(List *list, int n); extern List *list_delete_cell(List *list, ListCell *cell); diff --git a/ext/pg_query/include/nodes/plannodes.h b/ext/pg_query/include/nodes/plannodes.h index 83e01074..90f02ce6 100644 --- a/ext/pg_query/include/nodes/plannodes.h +++ b/ext/pg_query/include/nodes/plannodes.h @@ -418,14 +418,28 @@ typedef struct IndexScan * index-only scan, in which the data comes from the index not the heap. * Because of this, *all* Vars in the plan node's targetlist, qual, and * index expressions reference index columns and have varno = INDEX_VAR. - * Hence we do not need separate indexqualorig and indexorderbyorig lists, - * since their contents would be equivalent to indexqual and indexorderby. + * + * We could almost use indexqual directly against the index's output tuple + * when rechecking lossy index operators, but that won't work for quals on + * index columns that are not retrievable. Hence, recheckqual is needed + * for rechecks: it expresses the same condition as indexqual, but using + * only index columns that are retrievable. (We will not generate an + * index-only scan if this is not possible. An example is that if an + * index has table column "x" in a retrievable index column "ind1", plus + * an expression f(x) in a non-retrievable column "ind2", an indexable + * query on f(x) will use "ind2" in indexqual and f(ind1) in recheckqual. + * Without the "ind1" column, an index-only scan would be disallowed.) + * + * We don't currently need a recheckable equivalent of indexorderby, + * because we don't support lossy operators in index ORDER BY. * * To help EXPLAIN interpret the index Vars for display, we provide * indextlist, which represents the contents of the index as a targetlist * with one TLE per index column. Vars appearing in this list reference * the base table, and this is the only field in the plan node that may - * contain such Vars. + * contain such Vars. Also, for the convenience of setrefs.c, TLEs in + * indextlist are marked as resjunk if they correspond to columns that + * the index AM cannot reconstruct. * ---------------- */ typedef struct IndexOnlyScan @@ -436,6 +450,7 @@ typedef struct IndexOnlyScan List *indexorderby; /* list of index ORDER BY exprs */ List *indextlist; /* TargetEntry list describing index's cols */ ScanDirection indexorderdir; /* forward or backward or don't care */ + List *recheckqual; /* index quals in recheckable form */ } IndexOnlyScan; /* ---------------- diff --git a/ext/pg_query/include/optimizer/optimizer.h b/ext/pg_query/include/optimizer/optimizer.h index 3c588def..4729cd01 100644 --- a/ext/pg_query/include/optimizer/optimizer.h +++ b/ext/pg_query/include/optimizer/optimizer.h @@ -24,11 +24,6 @@ #include "nodes/parsenodes.h" -/* Test if an expression node represents a SRF call. Beware multiple eval! */ -#define IS_SRF_CALL(node) \ - ((IsA(node, FuncExpr) && ((FuncExpr *) (node))->funcretset) || \ - (IsA(node, OpExpr) && ((OpExpr *) (node))->opretset)) - /* * We don't want to include nodes/pathnodes.h here, because non-planner * code should generally treat PlannerInfo as an opaque typedef. diff --git a/ext/pg_query/include/parser/gram.h b/ext/pg_query/include/parser/gram.h index 7cae4f3b..243349f1 100644 --- a/ext/pg_query/include/parser/gram.h +++ b/ext/pg_query/include/parser/gram.h @@ -363,7 +363,7 @@ REASSIGN = 579, RECHECK = 580, RECURSIVE = 581, - REF = 582, + REF_P = 582, REFERENCES = 583, REFERENCING = 584, REFRESH = 585, @@ -840,7 +840,7 @@ #define REASSIGN 579 #define RECHECK 580 #define RECURSIVE 581 -#define REF 582 +#define REF_P 582 #define REFERENCES 583 #define REFERENCING 584 #define REFRESH 585 diff --git a/ext/pg_query/include/parser/kwlist.h b/ext/pg_query/include/parser/kwlist.h index 08f22ce2..4121a53b 100644 --- a/ext/pg_query/include/parser/kwlist.h +++ b/ext/pg_query/include/parser/kwlist.h @@ -330,7 +330,7 @@ PG_KEYWORD("real", REAL, COL_NAME_KEYWORD) PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD) PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD) PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD) -PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD) +PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD) PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD) PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD) PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD) diff --git a/ext/pg_query/include/parser/parse_coerce.h b/ext/pg_query/include/parser/parse_coerce.h index 8686eaac..9481d807 100644 --- a/ext/pg_query/include/parser/parse_coerce.h +++ b/ext/pg_query/include/parser/parse_coerce.h @@ -70,6 +70,7 @@ extern Oid select_common_type(ParseState *pstate, List *exprs, extern Node *coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context); +extern bool verify_common_type(Oid common_type, List *exprs); extern bool check_generic_type_consistency(const Oid *actual_arg_types, const Oid *declared_arg_types, diff --git a/ext/pg_query/include/pg_config.h b/ext/pg_query/include/pg_config.h index 3456af53..7808cc8d 100644 --- a/ext/pg_query/include/pg_config.h +++ b/ext/pg_query/include/pg_config.h @@ -317,9 +317,6 @@ /* Define to 1 if you have the `ldap' library (-lldap). */ /* #undef HAVE_LIBLDAP */ -/* Define to 1 if you have the `ldap_r' library (-lldap_r). */ -/* #undef HAVE_LIBLDAP_R */ - /* Define to 1 if you have the `m' library (-lm). */ #define HAVE_LIBM 1 @@ -474,6 +471,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_SECURITY_PAM_APPL_H */ +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + /* Define to 1 if you have the `setproctitle' function. */ /* #undef HAVE_SETPROCTITLE */ @@ -685,7 +685,7 @@ /* #undef HAVE_X509_GET_SIGNATURE_NID */ /* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ -#define HAVE_X86_64_POPCNTQ 1 +/* #undef HAVE_X86_64_POPCNTQ */ /* Define to 1 if the system has the type `_Bool'. */ #define HAVE__BOOL 1 @@ -708,6 +708,9 @@ /* Define to 1 if your compiler understands __builtin_ctz. */ #define HAVE__BUILTIN_CTZ 1 +/* Define to 1 if your compiler understands __builtin_frame_address. */ +#define HAVE__BUILTIN_FRAME_ADDRESS 1 + /* Define to 1 if your compiler understands __builtin_$op_overflow. */ #define HAVE__BUILTIN_OP_OVERFLOW 1 @@ -727,7 +730,7 @@ /* #undef HAVE__CPUID */ /* Define to 1 if you have __get_cpuid. */ -#define HAVE__GET_CPUID 1 +/* #undef HAVE__GET_CPUID */ /* Define to 1 if your compiler understands _Static_assert. */ #define HAVE__STATIC_ASSERT 1 @@ -757,7 +760,7 @@ #define PACKAGE_NAME "PostgreSQL" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PostgreSQL 13.3" +#define PACKAGE_STRING "PostgreSQL 13.8" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "postgresql" @@ -766,7 +769,7 @@ #define PACKAGE_URL "https://www.postgresql.org/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "13.3" +#define PACKAGE_VERSION "13.8" /* Define to the name of a signed 128-bit integer type. */ #define PG_INT128_TYPE __int128 @@ -785,7 +788,7 @@ #define PG_MAJORVERSION_NUM 13 /* PostgreSQL minor version number */ -#define PG_MINORVERSION_NUM 3 +#define PG_MINORVERSION_NUM 8 /* Define to best printf format archetype, usually gnu_printf if available. */ #define PG_PRINTF_ATTRIBUTE printf @@ -794,13 +797,13 @@ #define PG_USE_STDBOOL 1 /* PostgreSQL version as a string */ -#define PG_VERSION "13.3" +#define PG_VERSION "13.8" /* PostgreSQL version as a number */ -#define PG_VERSION_NUM 130003 +#define PG_VERSION_NUM 130008 /* A string containing the version number, platform, and C compiler */ -#define PG_VERSION_STR "PostgreSQL 13.3 on x86_64-apple-darwin19.6.0, compiled by Apple clang version 12.0.0 (clang-1200.0.32.29), 64-bit" +#define PG_VERSION_STR "PostgreSQL 13.8 on arm-apple-darwin21.6.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.202), 64-bit" /* Define to 1 to allow profiling output to be saved separately for each process. */ @@ -845,7 +848,7 @@ #define STRERROR_R_INT 1 /* Define to 1 to use ARMv8 CRC Extension. */ -/* #undef USE_ARMV8_CRC32C */ +#define USE_ARMV8_CRC32C 1 /* Define to 1 to use ARMv8 CRC Extension with a runtime check. */ /* #undef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK */ @@ -897,7 +900,7 @@ /* #undef USE_SSE42_CRC32C */ /* Define to 1 to use Intel SSE 4.2 CRC instructions with a runtime check. */ -#define USE_SSE42_CRC32C_WITH_RUNTIME_CHECK 1 +/* #undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK */ /* Define to build with systemd support. (--with-systemd) */ /* #undef USE_SYSTEMD */ diff --git a/ext/pg_query/include/pg_query.h b/ext/pg_query/include/pg_query.h index a11991a3..49efac4b 100644 --- a/ext/pg_query/include/pg_query.h +++ b/ext/pg_query/include/pg_query.h @@ -106,9 +106,9 @@ void pg_query_free_fingerprint_result(PgQueryFingerprintResult result); void pg_query_exit(void); // Postgres version information -#define PG_VERSION "13.3" +#define PG_VERSION "13.8" #define PG_MAJORVERSION "13" -#define PG_VERSION_NUM 130003 +#define PG_VERSION_NUM 130008 // Deprecated APIs below diff --git a/ext/pg_query/include/pg_query_fingerprint_defs.c b/ext/pg_query/include/pg_query_fingerprint_defs.c index 0f7c4c64..937b1d27 100644 --- a/ext/pg_query/include/pg_query_fingerprint_defs.c +++ b/ext/pg_query/include/pg_query_fingerprint_defs.c @@ -302,7 +302,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colcollations, node, "colcollations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colcollations) == 1 && linitial(node->colcollations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -318,7 +318,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coldefexprs, node, "coldefexprs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coldefexprs) == 1 && linitial(node->coldefexprs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -334,7 +334,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colexprs, node, "colexprs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colexprs) == 1 && linitial(node->colexprs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -350,7 +350,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colnames, node, "colnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colnames) == 1 && linitial(node->colnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -366,7 +366,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coltypes, node, "coltypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coltypes) == 1 && linitial(node->coltypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -382,7 +382,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coltypmods, node, "coltypmods", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coltypmods) == 1 && linitial(node->coltypmods) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -432,7 +432,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ns_names, node, "ns_names", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ns_names) == 1 && linitial(node->ns_names) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -448,7 +448,7 @@ _fingerprintTableFunc(FingerprintContext *ctx, const TableFunc *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ns_uris, node, "ns_uris", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ns_uris) == 1 && linitial(node->ns_uris) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -646,7 +646,7 @@ _fingerprintAggref(FingerprintContext *ctx, const Aggref *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->aggargtypes, node, "aggargtypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->aggargtypes) == 1 && linitial(node->aggargtypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -669,7 +669,7 @@ _fingerprintAggref(FingerprintContext *ctx, const Aggref *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->aggdirectargs, node, "aggdirectargs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->aggdirectargs) == 1 && linitial(node->aggdirectargs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -685,7 +685,7 @@ _fingerprintAggref(FingerprintContext *ctx, const Aggref *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->aggdistinct, node, "aggdistinct", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->aggdistinct) == 1 && linitial(node->aggdistinct) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -738,7 +738,7 @@ _fingerprintAggref(FingerprintContext *ctx, const Aggref *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->aggorder, node, "aggorder", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->aggorder) == 1 && linitial(node->aggorder) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -783,7 +783,7 @@ _fingerprintAggref(FingerprintContext *ctx, const Aggref *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -820,7 +820,7 @@ _fingerprintGroupingFunc(FingerprintContext *ctx, const GroupingFunc *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -836,7 +836,7 @@ _fingerprintGroupingFunc(FingerprintContext *ctx, const GroupingFunc *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->cols, node, "cols", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->cols) == 1 && linitial(node->cols) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -854,7 +854,7 @@ _fingerprintGroupingFunc(FingerprintContext *ctx, const GroupingFunc *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->refs, node, "refs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->refs) == 1 && linitial(node->refs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -892,7 +892,7 @@ _fingerprintWindowFunc(FingerprintContext *ctx, const WindowFunc *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1015,7 +1015,7 @@ _fingerprintSubscriptingRef(FingerprintContext *ctx, const SubscriptingRef *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->reflowerindexpr, node, "reflowerindexpr", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->reflowerindexpr) == 1 && linitial(node->reflowerindexpr) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1038,7 +1038,7 @@ _fingerprintSubscriptingRef(FingerprintContext *ctx, const SubscriptingRef *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->refupperindexpr, node, "refupperindexpr", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->refupperindexpr) == 1 && linitial(node->refupperindexpr) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1059,7 +1059,7 @@ _fingerprintFuncExpr(FingerprintContext *ctx, const FuncExpr *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1161,7 +1161,7 @@ _fingerprintOpExpr(FingerprintContext *ctx, const OpExpr *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1224,7 +1224,7 @@ _fingerprintScalarArrayOpExpr(FingerprintContext *ctx, const ScalarArrayOpExpr * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1273,7 +1273,7 @@ _fingerprintBoolExpr(FingerprintContext *ctx, const BoolExpr *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1303,7 +1303,7 @@ _fingerprintSubLink(FingerprintContext *ctx, const SubLink *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->operName, node, "operName", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->operName) == 1 && linitial(node->operName) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1370,7 +1370,7 @@ _fingerprintSubPlan(FingerprintContext *ctx, const SubPlan *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1407,7 +1407,7 @@ _fingerprintSubPlan(FingerprintContext *ctx, const SubPlan *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->parParam, node, "parParam", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->parParam) == 1 && linitial(node->parParam) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1428,7 +1428,7 @@ _fingerprintSubPlan(FingerprintContext *ctx, const SubPlan *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->paramIds, node, "paramIds", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->paramIds) == 1 && linitial(node->paramIds) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1463,7 +1463,7 @@ _fingerprintSubPlan(FingerprintContext *ctx, const SubPlan *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->setParam, node, "setParam", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->setParam) == 1 && linitial(node->setParam) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1523,7 +1523,7 @@ _fingerprintAlternativeSubPlan(FingerprintContext *ctx, const AlternativeSubPlan hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->subplans, node, "subplans", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->subplans) == 1 && linitial(node->subplans) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1611,7 +1611,7 @@ _fingerprintFieldStore(FingerprintContext *ctx, const FieldStore *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fieldnums, node, "fieldnums", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fieldnums) == 1 && linitial(node->fieldnums) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1627,7 +1627,7 @@ _fingerprintFieldStore(FingerprintContext *ctx, const FieldStore *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->newvals, node, "newvals", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->newvals) == 1 && linitial(node->newvals) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -1899,7 +1899,7 @@ _fingerprintCaseExpr(FingerprintContext *ctx, const CaseExpr *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2041,7 +2041,7 @@ _fingerprintArrayExpr(FingerprintContext *ctx, const ArrayExpr *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->elements, node, "elements", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->elements) == 1 && linitial(node->elements) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2069,7 +2069,7 @@ _fingerprintRowExpr(FingerprintContext *ctx, const RowExpr *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2085,7 +2085,7 @@ _fingerprintRowExpr(FingerprintContext *ctx, const RowExpr *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colnames, node, "colnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colnames) == 1 && linitial(node->colnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2120,7 +2120,7 @@ _fingerprintRowCompareExpr(FingerprintContext *ctx, const RowCompareExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->inputcollids, node, "inputcollids", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->inputcollids) == 1 && linitial(node->inputcollids) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2136,7 +2136,7 @@ _fingerprintRowCompareExpr(FingerprintContext *ctx, const RowCompareExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->largs, node, "largs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->largs) == 1 && linitial(node->largs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2152,7 +2152,7 @@ _fingerprintRowCompareExpr(FingerprintContext *ctx, const RowCompareExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opfamilies, node, "opfamilies", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opfamilies) == 1 && linitial(node->opfamilies) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2168,7 +2168,7 @@ _fingerprintRowCompareExpr(FingerprintContext *ctx, const RowCompareExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opnos, node, "opnos", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opnos) == 1 && linitial(node->opnos) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2184,7 +2184,7 @@ _fingerprintRowCompareExpr(FingerprintContext *ctx, const RowCompareExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->rargs, node, "rargs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->rargs) == 1 && linitial(node->rargs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2210,7 +2210,7 @@ _fingerprintCoalesceExpr(FingerprintContext *ctx, const CoalesceExpr *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2247,7 +2247,7 @@ _fingerprintMinMaxExpr(FingerprintContext *ctx, const MinMaxExpr *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2322,7 +2322,7 @@ _fingerprintXmlExpr(FingerprintContext *ctx, const XmlExpr *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->arg_names, node, "arg_names", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->arg_names) == 1 && linitial(node->arg_names) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2338,7 +2338,7 @@ _fingerprintXmlExpr(FingerprintContext *ctx, const XmlExpr *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2361,7 +2361,7 @@ _fingerprintXmlExpr(FingerprintContext *ctx, const XmlExpr *node, const void *pa hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->named_args, node, "named_args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->named_args) == 1 && linitial(node->named_args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2789,7 +2789,7 @@ _fingerprintJoinExpr(FingerprintContext *ctx, const JoinExpr *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->usingClause, node, "usingClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->usingClause) == 1 && linitial(node->usingClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2810,7 +2810,7 @@ _fingerprintFromExpr(FingerprintContext *ctx, const FromExpr *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fromlist, node, "fromlist", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fromlist) == 1 && linitial(node->fromlist) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2853,7 +2853,7 @@ _fingerprintOnConflictExpr(FingerprintContext *ctx, const OnConflictExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->arbiterElems, node, "arbiterElems", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->arbiterElems) == 1 && linitial(node->arbiterElems) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2900,7 +2900,7 @@ _fingerprintOnConflictExpr(FingerprintContext *ctx, const OnConflictExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->exclRelTlist, node, "exclRelTlist", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->exclRelTlist) == 1 && linitial(node->exclRelTlist) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2916,7 +2916,7 @@ _fingerprintOnConflictExpr(FingerprintContext *ctx, const OnConflictExpr *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->onConflictSet, node, "onConflictSet", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->onConflictSet) == 1 && linitial(node->onConflictSet) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2959,7 +2959,7 @@ _fingerprintIntoClause(FingerprintContext *ctx, const IntoClause *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colNames, node, "colNames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colNames) == 1 && linitial(node->colNames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -2980,7 +2980,7 @@ _fingerprintIntoClause(FingerprintContext *ctx, const IntoClause *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3081,7 +3081,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->constraintDeps, node, "constraintDeps", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->constraintDeps) == 1 && linitial(node->constraintDeps) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3097,7 +3097,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->cteList, node, "cteList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->cteList) == 1 && linitial(node->cteList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3113,7 +3113,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->distinctClause, node, "distinctClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->distinctClause) == 1 && linitial(node->distinctClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3129,7 +3129,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->groupClause, node, "groupClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->groupClause) == 1 && linitial(node->groupClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3145,7 +3145,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->groupingSets, node, "groupingSets", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->groupingSets) == 1 && linitial(node->groupingSets) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3320,7 +3320,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->returningList, node, "returningList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->returningList) == 1 && linitial(node->returningList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3336,7 +3336,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->rowMarks, node, "rowMarks", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->rowMarks) == 1 && linitial(node->rowMarks) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3352,7 +3352,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->rtable, node, "rtable", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->rtable) == 1 && linitial(node->rtable) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3385,7 +3385,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->sortClause, node, "sortClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->sortClause) == 1 && linitial(node->sortClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3415,7 +3415,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->targetList, node, "targetList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->targetList) == 1 && linitial(node->targetList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3448,7 +3448,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->windowClause, node, "windowClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->windowClause) == 1 && linitial(node->windowClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3464,7 +3464,7 @@ _fingerprintQuery(FingerprintContext *ctx, const Query *node, const void *parent hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->withCheckOptions, node, "withCheckOptions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->withCheckOptions) == 1 && linitial(node->withCheckOptions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3485,7 +3485,7 @@ _fingerprintInsertStmt(FingerprintContext *ctx, const InsertStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->cols, node, "cols", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->cols) == 1 && linitial(node->cols) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3540,7 +3540,7 @@ _fingerprintInsertStmt(FingerprintContext *ctx, const InsertStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->returningList, node, "returningList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->returningList) == 1 && linitial(node->returningList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3612,7 +3612,7 @@ _fingerprintDeleteStmt(FingerprintContext *ctx, const DeleteStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->returningList, node, "returningList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->returningList) == 1 && linitial(node->returningList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3628,7 +3628,7 @@ _fingerprintDeleteStmt(FingerprintContext *ctx, const DeleteStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->usingClause, node, "usingClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->usingClause) == 1 && linitial(node->usingClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3683,7 +3683,7 @@ _fingerprintUpdateStmt(FingerprintContext *ctx, const UpdateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fromClause, node, "fromClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fromClause) == 1 && linitial(node->fromClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3716,7 +3716,7 @@ _fingerprintUpdateStmt(FingerprintContext *ctx, const UpdateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->returningList, node, "returningList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->returningList) == 1 && linitial(node->returningList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3732,7 +3732,7 @@ _fingerprintUpdateStmt(FingerprintContext *ctx, const UpdateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->targetList, node, "targetList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->targetList) == 1 && linitial(node->targetList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3792,7 +3792,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->distinctClause, node, "distinctClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->distinctClause) == 1 && linitial(node->distinctClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3808,7 +3808,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fromClause, node, "fromClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fromClause) == 1 && linitial(node->fromClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3824,7 +3824,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->groupClause, node, "groupClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->groupClause) == 1 && linitial(node->groupClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3930,7 +3930,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->lockingClause, node, "lockingClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->lockingClause) == 1 && linitial(node->lockingClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3968,7 +3968,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->sortClause, node, "sortClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->sortClause) == 1 && linitial(node->sortClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -3984,7 +3984,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->targetList, node, "targetList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->targetList) == 1 && linitial(node->targetList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4000,7 +4000,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->valuesLists, node, "valuesLists", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->valuesLists) == 1 && linitial(node->valuesLists) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4033,7 +4033,7 @@ _fingerprintSelectStmt(FingerprintContext *ctx, const SelectStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->windowClause, node, "windowClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->windowClause) == 1 && linitial(node->windowClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4071,7 +4071,7 @@ _fingerprintAlterTableStmt(FingerprintContext *ctx, const AlterTableStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->cmds, node, "cmds", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->cmds) == 1 && linitial(node->cmds) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4166,6 +4166,11 @@ _fingerprintAlterTableCmd(FingerprintContext *ctx, const AlterTableCmd *node, co _fingerprintString(ctx, buffer); } + if (node->recurse) { + _fingerprintString(ctx, "recurse"); + _fingerprintString(ctx, "true"); + } + if (true) { _fingerprintString(ctx, "subtype"); _fingerprintString(ctx, _enumToStringAlterTableType(node->subtype)); @@ -4223,7 +4228,7 @@ _fingerprintAlterDomainStmt(FingerprintContext *ctx, const AlterDomainStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->typeName, node, "typeName", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->typeName) == 1 && linitial(node->typeName) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4249,7 +4254,7 @@ _fingerprintSetOperationStmt(FingerprintContext *ctx, const SetOperationStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colCollations, node, "colCollations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colCollations) == 1 && linitial(node->colCollations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4265,7 +4270,7 @@ _fingerprintSetOperationStmt(FingerprintContext *ctx, const SetOperationStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colTypes, node, "colTypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colTypes) == 1 && linitial(node->colTypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4281,7 +4286,7 @@ _fingerprintSetOperationStmt(FingerprintContext *ctx, const SetOperationStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colTypmods, node, "colTypmods", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colTypmods) == 1 && linitial(node->colTypmods) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4297,7 +4302,7 @@ _fingerprintSetOperationStmt(FingerprintContext *ctx, const SetOperationStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->groupClauses, node, "groupClauses", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->groupClauses) == 1 && linitial(node->groupClauses) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4367,7 +4372,7 @@ _fingerprintGrantStmt(FingerprintContext *ctx, const GrantStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->grantees, node, "grantees", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->grantees) == 1 && linitial(node->grantees) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4388,7 +4393,7 @@ _fingerprintGrantStmt(FingerprintContext *ctx, const GrantStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->objects, node, "objects", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->objects) == 1 && linitial(node->objects) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4409,7 +4414,7 @@ _fingerprintGrantStmt(FingerprintContext *ctx, const GrantStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->privileges, node, "privileges", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->privileges) == 1 && linitial(node->privileges) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4445,7 +4450,7 @@ _fingerprintGrantRoleStmt(FingerprintContext *ctx, const GrantRoleStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->granted_roles, node, "granted_roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->granted_roles) == 1 && linitial(node->granted_roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4461,7 +4466,7 @@ _fingerprintGrantRoleStmt(FingerprintContext *ctx, const GrantRoleStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->grantee_roles, node, "grantee_roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->grantee_roles) == 1 && linitial(node->grantee_roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4521,7 +4526,7 @@ _fingerprintAlterDefaultPrivilegesStmt(FingerprintContext *ctx, const AlterDefau hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4583,7 +4588,7 @@ _fingerprintCopyStmt(FingerprintContext *ctx, const CopyStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->attlist, node, "attlist", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->attlist) == 1 && linitial(node->attlist) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4614,7 +4619,7 @@ _fingerprintCopyStmt(FingerprintContext *ctx, const CopyStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4691,7 +4696,7 @@ _fingerprintCreateStmt(FingerprintContext *ctx, const CreateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->constraints, node, "constraints", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->constraints) == 1 && linitial(node->constraints) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4712,7 +4717,7 @@ _fingerprintCreateStmt(FingerprintContext *ctx, const CreateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->inhRelations, node, "inhRelations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->inhRelations) == 1 && linitial(node->inhRelations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4750,7 +4755,7 @@ _fingerprintCreateStmt(FingerprintContext *ctx, const CreateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4817,7 +4822,7 @@ _fingerprintCreateStmt(FingerprintContext *ctx, const CreateStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->tableElts, node, "tableElts", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->tableElts) == 1 && linitial(node->tableElts) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4843,7 +4848,7 @@ _fingerprintDefineStmt(FingerprintContext *ctx, const DefineStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4859,7 +4864,7 @@ _fingerprintDefineStmt(FingerprintContext *ctx, const DefineStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->definition, node, "definition", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->definition) == 1 && linitial(node->definition) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4875,7 +4880,7 @@ _fingerprintDefineStmt(FingerprintContext *ctx, const DefineStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->defnames, node, "defnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->defnames) == 1 && linitial(node->defnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4931,7 +4936,7 @@ _fingerprintDropStmt(FingerprintContext *ctx, const DropStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->objects, node, "objects", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->objects) == 1 && linitial(node->objects) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -4962,7 +4967,7 @@ _fingerprintTruncateStmt(FingerprintContext *ctx, const TruncateStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->relations, node, "relations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->relations) == 1 && linitial(node->relations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5059,7 +5064,7 @@ _fingerprintIndexStmt(FingerprintContext *ctx, const IndexStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->excludeOpNames, node, "excludeOpNames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->excludeOpNames) == 1 && linitial(node->excludeOpNames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5090,7 +5095,7 @@ _fingerprintIndexStmt(FingerprintContext *ctx, const IndexStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->indexIncludingParams, node, "indexIncludingParams", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->indexIncludingParams) == 1 && linitial(node->indexIncludingParams) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5113,7 +5118,7 @@ _fingerprintIndexStmt(FingerprintContext *ctx, const IndexStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->indexParams, node, "indexParams", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->indexParams) == 1 && linitial(node->indexParams) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5160,7 +5165,7 @@ _fingerprintIndexStmt(FingerprintContext *ctx, const IndexStmt *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5240,7 +5245,7 @@ _fingerprintCreateFunctionStmt(FingerprintContext *ctx, const CreateFunctionStmt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funcname, node, "funcname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funcname) == 1 && linitial(node->funcname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5252,22 +5257,8 @@ _fingerprintCreateFunctionStmt(FingerprintContext *ctx, const CreateFunctionStmt _fingerprintString(ctx, "true"); } - if (node->options != NULL && node->options->length > 0) { - XXH3_state_t* prev = XXH3_createState(); - XXH64_hash_t hash; - - XXH3_copyState(prev, ctx->xxh_state); - _fingerprintString(ctx, "options"); + // Intentionally ignoring node->options for fingerprinting - hash = XXH3_64bits_digest(ctx->xxh_state); - _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { - XXH3_copyState(ctx->xxh_state, prev); - if (ctx->write_tokens) - dlist_delete(dlist_tail_node(&ctx->tokens)); - } - XXH3_freeState(prev); - } if (node->parameters != NULL && node->parameters->length > 0) { XXH3_state_t* prev = XXH3_createState(); XXH64_hash_t hash; @@ -5277,7 +5268,7 @@ _fingerprintCreateFunctionStmt(FingerprintContext *ctx, const CreateFunctionStmt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->parameters, node, "parameters", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->parameters) == 1 && linitial(node->parameters) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5320,7 +5311,7 @@ _fingerprintAlterFunctionStmt(FingerprintContext *ctx, const AlterFunctionStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->actions, node, "actions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->actions) == 1 && linitial(node->actions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5354,22 +5345,8 @@ _fingerprintAlterFunctionStmt(FingerprintContext *ctx, const AlterFunctionStmt * static void _fingerprintDoStmt(FingerprintContext *ctx, const DoStmt *node, const void *parent, const char *field_name, unsigned int depth) { - if (node->args != NULL && node->args->length > 0) { - XXH3_state_t* prev = XXH3_createState(); - XXH64_hash_t hash; - - XXH3_copyState(prev, ctx->xxh_state); - _fingerprintString(ctx, "args"); + // Intentionally ignoring node->args for fingerprinting - hash = XXH3_64bits_digest(ctx->xxh_state); - _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { - XXH3_copyState(ctx->xxh_state, prev); - if (ctx->write_tokens) - dlist_delete(dlist_tail_node(&ctx->tokens)); - } - XXH3_freeState(prev); - } } static void @@ -5453,7 +5430,7 @@ _fingerprintRuleStmt(FingerprintContext *ctx, const RuleStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->actions, node, "actions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->actions) == 1 && linitial(node->actions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5519,10 +5496,7 @@ _fingerprintRuleStmt(FingerprintContext *ctx, const RuleStmt *node, const void * static void _fingerprintNotifyStmt(FingerprintContext *ctx, const NotifyStmt *node, const void *parent, const char *field_name, unsigned int depth) { - if (node->conditionname != NULL) { - _fingerprintString(ctx, "conditionname"); - _fingerprintString(ctx, node->conditionname); - } + // Intentionally ignoring node->conditionname for fingerprinting if (node->payload != NULL) { _fingerprintString(ctx, "payload"); @@ -5534,20 +5508,14 @@ _fingerprintNotifyStmt(FingerprintContext *ctx, const NotifyStmt *node, const vo static void _fingerprintListenStmt(FingerprintContext *ctx, const ListenStmt *node, const void *parent, const char *field_name, unsigned int depth) { - if (node->conditionname != NULL) { - _fingerprintString(ctx, "conditionname"); - _fingerprintString(ctx, node->conditionname); - } + // Intentionally ignoring node->conditionname for fingerprinting } static void _fingerprintUnlistenStmt(FingerprintContext *ctx, const UnlistenStmt *node, const void *parent, const char *field_name, unsigned int depth) { - if (node->conditionname != NULL) { - _fingerprintString(ctx, "conditionname"); - _fingerprintString(ctx, node->conditionname); - } + // Intentionally ignoring node->conditionname for fingerprinting } @@ -5584,7 +5552,7 @@ _fingerprintViewStmt(FingerprintContext *ctx, const ViewStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->aliases, node, "aliases", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->aliases) == 1 && linitial(node->aliases) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5600,7 +5568,7 @@ _fingerprintViewStmt(FingerprintContext *ctx, const ViewStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5692,7 +5660,7 @@ _fingerprintCreateDomainStmt(FingerprintContext *ctx, const CreateDomainStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->constraints, node, "constraints", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->constraints) == 1 && linitial(node->constraints) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5708,7 +5676,7 @@ _fingerprintCreateDomainStmt(FingerprintContext *ctx, const CreateDomainStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->domainname, node, "domainname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->domainname) == 1 && linitial(node->domainname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5751,7 +5719,7 @@ _fingerprintCreatedbStmt(FingerprintContext *ctx, const CreatedbStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5782,7 +5750,7 @@ _fingerprintDropdbStmt(FingerprintContext *ctx, const DropdbStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5808,7 +5776,7 @@ _fingerprintVacuumStmt(FingerprintContext *ctx, const VacuumStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5824,7 +5792,7 @@ _fingerprintVacuumStmt(FingerprintContext *ctx, const VacuumStmt *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->rels, node, "rels", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->rels) == 1 && linitial(node->rels) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5845,7 +5813,7 @@ _fingerprintExplainStmt(FingerprintContext *ctx, const ExplainStmt *node, const hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -5947,7 +5915,7 @@ _fingerprintCreateSeqStmt(FingerprintContext *ctx, const CreateSeqStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6002,7 +5970,7 @@ _fingerprintAlterSeqStmt(FingerprintContext *ctx, const AlterSeqStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6040,7 +6008,7 @@ _fingerprintVariableSetStmt(FingerprintContext *ctx, const VariableSetStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6096,7 +6064,7 @@ _fingerprintCreateTrigStmt(FingerprintContext *ctx, const CreateTrigStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6112,7 +6080,7 @@ _fingerprintCreateTrigStmt(FingerprintContext *ctx, const CreateTrigStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->columns, node, "columns", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->columns) == 1 && linitial(node->columns) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6157,7 +6125,7 @@ _fingerprintCreateTrigStmt(FingerprintContext *ctx, const CreateTrigStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funcname, node, "funcname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funcname) == 1 && linitial(node->funcname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6212,7 +6180,7 @@ _fingerprintCreateTrigStmt(FingerprintContext *ctx, const CreateTrigStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->transitionRels, node, "transitionRels", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->transitionRels) == 1 && linitial(node->transitionRels) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6255,7 +6223,7 @@ _fingerprintCreatePLangStmt(FingerprintContext *ctx, const CreatePLangStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->plhandler, node, "plhandler", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->plhandler) == 1 && linitial(node->plhandler) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6271,7 +6239,7 @@ _fingerprintCreatePLangStmt(FingerprintContext *ctx, const CreatePLangStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->plinline, node, "plinline", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->plinline) == 1 && linitial(node->plinline) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6297,7 +6265,7 @@ _fingerprintCreatePLangStmt(FingerprintContext *ctx, const CreatePLangStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->plvalidator, node, "plvalidator", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->plvalidator) == 1 && linitial(node->plvalidator) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6323,7 +6291,7 @@ _fingerprintCreateRoleStmt(FingerprintContext *ctx, const CreateRoleStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6361,7 +6329,7 @@ _fingerprintAlterRoleStmt(FingerprintContext *ctx, const AlterRoleStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6404,7 +6372,7 @@ _fingerprintDropRoleStmt(FingerprintContext *ctx, const DropRoleStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->roles, node, "roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->roles) == 1 && linitial(node->roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6437,7 +6405,7 @@ _fingerprintLockStmt(FingerprintContext *ctx, const LockStmt *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->relations, node, "relations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->relations) == 1 && linitial(node->relations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6458,7 +6426,7 @@ _fingerprintConstraintsSetStmt(FingerprintContext *ctx, const ConstraintsSetStmt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->constraints, node, "constraints", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->constraints) == 1 && linitial(node->constraints) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6555,7 +6523,7 @@ _fingerprintCreateSchemaStmt(FingerprintContext *ctx, const CreateSchemaStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->schemaElts, node, "schemaElts", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->schemaElts) == 1 && linitial(node->schemaElts) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6586,7 +6554,7 @@ _fingerprintAlterDatabaseStmt(FingerprintContext *ctx, const AlterDatabaseStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6678,7 +6646,7 @@ _fingerprintCreateConversionStmt(FingerprintContext *ctx, const CreateConversion hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->conversion_name, node, "conversion_name", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->conversion_name) == 1 && linitial(node->conversion_name) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6704,7 +6672,7 @@ _fingerprintCreateConversionStmt(FingerprintContext *ctx, const CreateConversion hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->func_name, node, "func_name", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->func_name) == 1 && linitial(node->func_name) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6823,7 +6791,7 @@ _fingerprintCreateOpClassStmt(FingerprintContext *ctx, const CreateOpClassStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->items, node, "items", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->items) == 1 && linitial(node->items) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6839,7 +6807,7 @@ _fingerprintCreateOpClassStmt(FingerprintContext *ctx, const CreateOpClassStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opclassname, node, "opclassname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opclassname) == 1 && linitial(node->opclassname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6855,7 +6823,7 @@ _fingerprintCreateOpClassStmt(FingerprintContext *ctx, const CreateOpClassStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opfamilyname, node, "opfamilyname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opfamilyname) == 1 && linitial(node->opfamilyname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6881,7 +6849,7 @@ _fingerprintCreateOpFamilyStmt(FingerprintContext *ctx, const CreateOpFamilyStmt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opfamilyname, node, "opfamilyname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opfamilyname) == 1 && linitial(node->opfamilyname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6912,7 +6880,7 @@ _fingerprintAlterOpFamilyStmt(FingerprintContext *ctx, const AlterOpFamilyStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->items, node, "items", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->items) == 1 && linitial(node->items) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6928,7 +6896,7 @@ _fingerprintAlterOpFamilyStmt(FingerprintContext *ctx, const AlterOpFamilyStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opfamilyname, node, "opfamilyname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opfamilyname) == 1 && linitial(node->opfamilyname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6949,7 +6917,7 @@ _fingerprintPrepareStmt(FingerprintContext *ctx, const PrepareStmt *node, const hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->argtypes, node, "argtypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->argtypes) == 1 && linitial(node->argtypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -6991,7 +6959,7 @@ _fingerprintExecuteStmt(FingerprintContext *ctx, const ExecuteStmt *node, const hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->params, node, "params", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->params) == 1 && linitial(node->params) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7052,7 +7020,7 @@ _fingerprintCreateTableSpaceStmt(FingerprintContext *ctx, const CreateTableSpace hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7308,7 +7276,7 @@ _fingerprintAlterOperatorStmt(FingerprintContext *ctx, const AlterOperatorStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7329,7 +7297,7 @@ _fingerprintAlterTypeStmt(FingerprintContext *ctx, const AlterTypeStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7345,7 +7313,7 @@ _fingerprintAlterTypeStmt(FingerprintContext *ctx, const AlterTypeStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->typeName, node, "typeName", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->typeName) == 1 && linitial(node->typeName) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7371,7 +7339,7 @@ _fingerprintDropOwnedStmt(FingerprintContext *ctx, const DropOwnedStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->roles, node, "roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->roles) == 1 && linitial(node->roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7409,7 +7377,7 @@ _fingerprintReassignOwnedStmt(FingerprintContext *ctx, const ReassignOwnedStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->roles, node, "roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->roles) == 1 && linitial(node->roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7430,7 +7398,7 @@ _fingerprintCompositeTypeStmt(FingerprintContext *ctx, const CompositeTypeStmt * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coldeflist, node, "coldeflist", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coldeflist) == 1 && linitial(node->coldeflist) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7468,7 +7436,7 @@ _fingerprintCreateEnumStmt(FingerprintContext *ctx, const CreateEnumStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->typeName, node, "typeName", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->typeName) == 1 && linitial(node->typeName) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7484,7 +7452,7 @@ _fingerprintCreateEnumStmt(FingerprintContext *ctx, const CreateEnumStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->vals, node, "vals", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->vals) == 1 && linitial(node->vals) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7505,7 +7473,7 @@ _fingerprintCreateRangeStmt(FingerprintContext *ctx, const CreateRangeStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->params, node, "params", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->params) == 1 && linitial(node->params) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7521,7 +7489,7 @@ _fingerprintCreateRangeStmt(FingerprintContext *ctx, const CreateRangeStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->typeName, node, "typeName", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->typeName) == 1 && linitial(node->typeName) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7567,7 +7535,7 @@ _fingerprintAlterEnumStmt(FingerprintContext *ctx, const AlterEnumStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->typeName, node, "typeName", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->typeName) == 1 && linitial(node->typeName) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7588,7 +7556,7 @@ _fingerprintAlterTSDictionaryStmt(FingerprintContext *ctx, const AlterTSDictiona hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->dictname, node, "dictname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->dictname) == 1 && linitial(node->dictname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7604,7 +7572,7 @@ _fingerprintAlterTSDictionaryStmt(FingerprintContext *ctx, const AlterTSDictiona hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7625,7 +7593,7 @@ _fingerprintAlterTSConfigurationStmt(FingerprintContext *ctx, const AlterTSConfi hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->cfgname, node, "cfgname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->cfgname) == 1 && linitial(node->cfgname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7641,7 +7609,7 @@ _fingerprintAlterTSConfigurationStmt(FingerprintContext *ctx, const AlterTSConfi hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->dicts, node, "dicts", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->dicts) == 1 && linitial(node->dicts) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7677,7 +7645,7 @@ _fingerprintAlterTSConfigurationStmt(FingerprintContext *ctx, const AlterTSConfi hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->tokentype, node, "tokentype", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->tokentype) == 1 && linitial(node->tokentype) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7703,7 +7671,7 @@ _fingerprintCreateFdwStmt(FingerprintContext *ctx, const CreateFdwStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->func_options, node, "func_options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->func_options) == 1 && linitial(node->func_options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7719,7 +7687,7 @@ _fingerprintCreateFdwStmt(FingerprintContext *ctx, const CreateFdwStmt *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7745,7 +7713,7 @@ _fingerprintAlterFdwStmt(FingerprintContext *ctx, const AlterFdwStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->func_options, node, "func_options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->func_options) == 1 && linitial(node->func_options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7761,7 +7729,7 @@ _fingerprintAlterFdwStmt(FingerprintContext *ctx, const AlterFdwStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7792,7 +7760,7 @@ _fingerprintCreateForeignServerStmt(FingerprintContext *ctx, const CreateForeign hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7833,7 +7801,7 @@ _fingerprintAlterForeignServerStmt(FingerprintContext *ctx, const AlterForeignSe hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7869,7 +7837,7 @@ _fingerprintCreateUserMappingStmt(FingerprintContext *ctx, const CreateUserMappi hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7912,7 +7880,7 @@ _fingerprintAlterUserMappingStmt(FingerprintContext *ctx, const AlterUserMapping hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -7992,7 +7960,7 @@ _fingerprintAlterTableSpaceOptionsStmt(FingerprintContext *ctx, const AlterTable hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8038,7 +8006,7 @@ _fingerprintAlterTableMoveAllStmt(FingerprintContext *ctx, const AlterTableMoveA hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->roles, node, "roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->roles) == 1 && linitial(node->roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8098,7 +8066,7 @@ _fingerprintCreateForeignTableStmt(FingerprintContext *ctx, const CreateForeignT hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8134,7 +8102,7 @@ _fingerprintImportForeignSchemaStmt(FingerprintContext *ctx, const ImportForeign hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8160,7 +8128,7 @@ _fingerprintImportForeignSchemaStmt(FingerprintContext *ctx, const ImportForeign hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->table_list, node, "table_list", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->table_list) == 1 && linitial(node->table_list) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8191,7 +8159,7 @@ _fingerprintCreateExtensionStmt(FingerprintContext *ctx, const CreateExtensionSt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8217,7 +8185,7 @@ _fingerprintAlterExtensionStmt(FingerprintContext *ctx, const AlterExtensionStmt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8282,7 +8250,7 @@ _fingerprintCreateEventTrigStmt(FingerprintContext *ctx, const CreateEventTrigSt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funcname, node, "funcname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funcname) == 1 && linitial(node->funcname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8303,7 +8271,7 @@ _fingerprintCreateEventTrigStmt(FingerprintContext *ctx, const CreateEventTrigSt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->whenclause, node, "whenclause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->whenclause) == 1 && linitial(node->whenclause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8442,7 +8410,7 @@ _fingerprintCreatePolicyStmt(FingerprintContext *ctx, const CreatePolicyStmt *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->roles, node, "roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->roles) == 1 && linitial(node->roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8519,7 +8487,7 @@ _fingerprintAlterPolicyStmt(FingerprintContext *ctx, const AlterPolicyStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->roles, node, "roles", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->roles) == 1 && linitial(node->roles) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8651,7 +8619,7 @@ _fingerprintCreateAmStmt(FingerprintContext *ctx, const CreateAmStmt *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->handler_name, node, "handler_name", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->handler_name) == 1 && linitial(node->handler_name) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8677,7 +8645,7 @@ _fingerprintCreatePublicationStmt(FingerprintContext *ctx, const CreatePublicati hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8698,7 +8666,7 @@ _fingerprintCreatePublicationStmt(FingerprintContext *ctx, const CreatePublicati hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->tables, node, "tables", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->tables) == 1 && linitial(node->tables) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8724,7 +8692,7 @@ _fingerprintAlterPublicationStmt(FingerprintContext *ctx, const AlterPublication hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8750,7 +8718,7 @@ _fingerprintAlterPublicationStmt(FingerprintContext *ctx, const AlterPublication hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->tables, node, "tables", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->tables) == 1 && linitial(node->tables) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8776,7 +8744,7 @@ _fingerprintCreateSubscriptionStmt(FingerprintContext *ctx, const CreateSubscrip hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8792,7 +8760,7 @@ _fingerprintCreateSubscriptionStmt(FingerprintContext *ctx, const CreateSubscrip hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->publication, node, "publication", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->publication) == 1 && linitial(node->publication) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8828,7 +8796,7 @@ _fingerprintAlterSubscriptionStmt(FingerprintContext *ctx, const AlterSubscripti hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8844,7 +8812,7 @@ _fingerprintAlterSubscriptionStmt(FingerprintContext *ctx, const AlterSubscripti hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->publication, node, "publication", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->publication) == 1 && linitial(node->publication) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8890,7 +8858,7 @@ _fingerprintCreateStatsStmt(FingerprintContext *ctx, const CreateStatsStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->defnames, node, "defnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->defnames) == 1 && linitial(node->defnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8906,7 +8874,7 @@ _fingerprintCreateStatsStmt(FingerprintContext *ctx, const CreateStatsStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->exprs, node, "exprs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->exprs) == 1 && linitial(node->exprs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8927,7 +8895,7 @@ _fingerprintCreateStatsStmt(FingerprintContext *ctx, const CreateStatsStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->relations, node, "relations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->relations) == 1 && linitial(node->relations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8943,7 +8911,7 @@ _fingerprintCreateStatsStmt(FingerprintContext *ctx, const CreateStatsStmt *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->stat_types, node, "stat_types", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->stat_types) == 1 && linitial(node->stat_types) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -8969,7 +8937,7 @@ _fingerprintAlterCollationStmt(FingerprintContext *ctx, const AlterCollationStmt hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->collname, node, "collname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->collname) == 1 && linitial(node->collname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9029,7 +8997,7 @@ _fingerprintAlterStatsStmt(FingerprintContext *ctx, const AlterStatsStmt *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->defnames, node, "defnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->defnames) == 1 && linitial(node->defnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9089,7 +9057,7 @@ _fingerprintA_Expr(FingerprintContext *ctx, const A_Expr *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->name, node, "name", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->name) == 1 && linitial(node->name) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9127,7 +9095,7 @@ _fingerprintColumnRef(FingerprintContext *ctx, const ColumnRef *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fields, node, "fields", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fields) == 1 && linitial(node->fields) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9184,7 +9152,7 @@ _fingerprintFuncCall(FingerprintContext *ctx, const FuncCall *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->agg_order, node, "agg_order", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->agg_order) == 1 && linitial(node->agg_order) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9210,7 +9178,7 @@ _fingerprintFuncCall(FingerprintContext *ctx, const FuncCall *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9231,7 +9199,7 @@ _fingerprintFuncCall(FingerprintContext *ctx, const FuncCall *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funcname, node, "funcname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funcname) == 1 && linitial(node->funcname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9337,7 +9305,7 @@ _fingerprintA_Indirection(FingerprintContext *ctx, const A_Indirection *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->indirection, node, "indirection", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->indirection) == 1 && linitial(node->indirection) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9358,7 +9326,7 @@ _fingerprintA_ArrayExpr(FingerprintContext *ctx, const A_ArrayExpr *node, const hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->elements, node, "elements", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->elements) == 1 && linitial(node->elements) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9381,7 +9349,7 @@ _fingerprintResTarget(FingerprintContext *ctx, const ResTarget *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->indirection, node, "indirection", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->indirection) == 1 && linitial(node->indirection) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9520,7 +9488,7 @@ _fingerprintCollateClause(FingerprintContext *ctx, const CollateClause *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->collname, node, "collname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->collname) == 1 && linitial(node->collname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9572,7 +9540,7 @@ _fingerprintSortBy(FingerprintContext *ctx, const SortBy *node, const void *pare hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->useOp, node, "useOp", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->useOp) == 1 && linitial(node->useOp) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9624,7 +9592,7 @@ _fingerprintWindowDef(FingerprintContext *ctx, const WindowDef *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->orderClause, node, "orderClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->orderClause) == 1 && linitial(node->orderClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9640,7 +9608,7 @@ _fingerprintWindowDef(FingerprintContext *ctx, const WindowDef *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->partitionClause, node, "partitionClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->partitionClause) == 1 && linitial(node->partitionClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9744,7 +9712,7 @@ _fingerprintRangeFunction(FingerprintContext *ctx, const RangeFunction *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coldeflist, node, "coldeflist", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coldeflist) == 1 && linitial(node->coldeflist) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9760,7 +9728,7 @@ _fingerprintRangeFunction(FingerprintContext *ctx, const RangeFunction *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->functions, node, "functions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->functions) == 1 && linitial(node->functions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9796,7 +9764,7 @@ _fingerprintRangeTableSample(FingerprintContext *ctx, const RangeTableSample *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9814,7 +9782,7 @@ _fingerprintRangeTableSample(FingerprintContext *ctx, const RangeTableSample *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->method, node, "method", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->method) == 1 && linitial(node->method) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9886,7 +9854,7 @@ _fingerprintRangeTableFunc(FingerprintContext *ctx, const RangeTableFunc *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->columns, node, "columns", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->columns) == 1 && linitial(node->columns) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -9926,7 +9894,7 @@ _fingerprintRangeTableFunc(FingerprintContext *ctx, const RangeTableFunc *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->namespaces, node, "namespaces", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->namespaces) == 1 && linitial(node->namespaces) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10037,7 +10005,7 @@ _fingerprintTypeName(FingerprintContext *ctx, const TypeName *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->arrayBounds, node, "arrayBounds", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->arrayBounds) == 1 && linitial(node->arrayBounds) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10055,7 +10023,7 @@ _fingerprintTypeName(FingerprintContext *ctx, const TypeName *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->names, node, "names", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->names) == 1 && linitial(node->names) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10095,7 +10063,7 @@ _fingerprintTypeName(FingerprintContext *ctx, const TypeName *node, const void * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->typmods, node, "typmods", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->typmods) == 1 && linitial(node->typmods) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10145,7 +10113,7 @@ _fingerprintColumnDef(FingerprintContext *ctx, const ColumnDef *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->constraints, node, "constraints", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->constraints) == 1 && linitial(node->constraints) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10178,7 +10146,7 @@ _fingerprintColumnDef(FingerprintContext *ctx, const ColumnDef *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fdwoptions, node, "fdwoptions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fdwoptions) == 1 && linitial(node->fdwoptions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10292,7 +10260,7 @@ _fingerprintIndexElem(FingerprintContext *ctx, const IndexElem *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->collation, node, "collation", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->collation) == 1 && linitial(node->collation) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10340,7 +10308,7 @@ _fingerprintIndexElem(FingerprintContext *ctx, const IndexElem *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opclass, node, "opclass", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opclass) == 1 && linitial(node->opclass) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10356,7 +10324,7 @@ _fingerprintIndexElem(FingerprintContext *ctx, const IndexElem *node, const void hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opclassopts, node, "opclassopts", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opclassopts) == 1 && linitial(node->opclassopts) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10407,7 +10375,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->exclusions, node, "exclusions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->exclusions) == 1 && linitial(node->exclusions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10423,7 +10391,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->fk_attrs, node, "fk_attrs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->fk_attrs) == 1 && linitial(node->fk_attrs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10463,7 +10431,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->including, node, "including", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->including) == 1 && linitial(node->including) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10504,7 +10472,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->keys, node, "keys", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->keys) == 1 && linitial(node->keys) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10522,7 +10490,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->old_conpfeqop, node, "old_conpfeqop", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->old_conpfeqop) == 1 && linitial(node->old_conpfeqop) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10545,7 +10513,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->options, node, "options", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->options) == 1 && linitial(node->options) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10561,7 +10529,7 @@ _fingerprintConstraint(FingerprintContext *ctx, const Constraint *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->pk_attrs, node, "pk_attrs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->pk_attrs) == 1 && linitial(node->pk_attrs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10706,7 +10674,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->colcollations, node, "colcollations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->colcollations) == 1 && linitial(node->colcollations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10722,7 +10690,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coltypes, node, "coltypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coltypes) == 1 && linitial(node->coltypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10738,7 +10706,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->coltypmods, node, "coltypmods", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->coltypmods) == 1 && linitial(node->coltypmods) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10815,7 +10783,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->functions, node, "functions", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->functions) == 1 && linitial(node->functions) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10856,7 +10824,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->joinaliasvars, node, "joinaliasvars", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->joinaliasvars) == 1 && linitial(node->joinaliasvars) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10872,7 +10840,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->joinleftcols, node, "joinleftcols", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->joinleftcols) == 1 && linitial(node->joinleftcols) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10895,7 +10863,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->joinrightcols, node, "joinrightcols", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->joinrightcols) == 1 && linitial(node->joinrightcols) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -10953,7 +10921,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->securityQuals, node, "securityQuals", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->securityQuals) == 1 && linitial(node->securityQuals) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11060,7 +11028,7 @@ _fingerprintRangeTblEntry(FingerprintContext *ctx, const RangeTblEntry *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->values_lists, node, "values_lists", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->values_lists) == 1 && linitial(node->values_lists) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11081,7 +11049,7 @@ _fingerprintRangeTblFunction(FingerprintContext *ctx, const RangeTblFunction *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funccolcollations, node, "funccolcollations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funccolcollations) == 1 && linitial(node->funccolcollations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11104,7 +11072,7 @@ _fingerprintRangeTblFunction(FingerprintContext *ctx, const RangeTblFunction *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funccolnames, node, "funccolnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funccolnames) == 1 && linitial(node->funccolnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11120,7 +11088,7 @@ _fingerprintRangeTblFunction(FingerprintContext *ctx, const RangeTblFunction *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funccoltypes, node, "funccoltypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funccoltypes) == 1 && linitial(node->funccoltypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11136,7 +11104,7 @@ _fingerprintRangeTblFunction(FingerprintContext *ctx, const RangeTblFunction *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->funccoltypmods, node, "funccoltypmods", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->funccoltypmods) == 1 && linitial(node->funccoltypmods) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11189,7 +11157,7 @@ _fingerprintTableSampleClause(FingerprintContext *ctx, const TableSampleClause * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->args, node, "args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->args) == 1 && linitial(node->args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11312,7 +11280,7 @@ _fingerprintGroupingSet(FingerprintContext *ctx, const GroupingSet *node, const hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->content, node, "content", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->content) == 1 && linitial(node->content) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11398,7 +11366,7 @@ _fingerprintWindowClause(FingerprintContext *ctx, const WindowClause *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->orderClause, node, "orderClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->orderClause) == 1 && linitial(node->orderClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11414,7 +11382,7 @@ _fingerprintWindowClause(FingerprintContext *ctx, const WindowClause *node, cons hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->partitionClause, node, "partitionClause", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->partitionClause) == 1 && linitial(node->partitionClause) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11476,7 +11444,7 @@ _fingerprintObjectWithArgs(FingerprintContext *ctx, const ObjectWithArgs *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->objargs, node, "objargs", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->objargs) == 1 && linitial(node->objargs) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11492,7 +11460,7 @@ _fingerprintObjectWithArgs(FingerprintContext *ctx, const ObjectWithArgs *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->objname, node, "objname", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->objname) == 1 && linitial(node->objname) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11513,7 +11481,7 @@ _fingerprintAccessPriv(FingerprintContext *ctx, const AccessPriv *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->cols, node, "cols", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->cols) == 1 && linitial(node->cols) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11539,7 +11507,7 @@ _fingerprintCreateOpClassItem(FingerprintContext *ctx, const CreateOpClassItem * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->class_args, node, "class_args", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->class_args) == 1 && linitial(node->class_args) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11586,7 +11554,7 @@ _fingerprintCreateOpClassItem(FingerprintContext *ctx, const CreateOpClassItem * hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->order_family, node, "order_family", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->order_family) == 1 && linitial(node->order_family) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11639,6 +11607,13 @@ _fingerprintTableLikeClause(FingerprintContext *ctx, const TableLikeClause *node XXH3_freeState(prev); } + if (node->relationOid != 0) { + char buffer[50]; + sprintf(buffer, "%d", node->relationOid); + _fingerprintString(ctx, "relationOid"); + _fingerprintString(ctx, buffer); + } + } static void @@ -11683,10 +11658,7 @@ _fingerprintFunctionParameter(FingerprintContext *ctx, const FunctionParameter * _fingerprintString(ctx, _enumToStringFunctionParameterMode(node->mode)); } - if (node->name != NULL) { - _fingerprintString(ctx, "name"); - _fingerprintString(ctx, node->name); - } + // Intentionally ignoring node->name for fingerprinting } @@ -11702,7 +11674,7 @@ _fingerprintLockingClause(FingerprintContext *ctx, const LockingClause *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->lockedRels, node, "lockedRels", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->lockedRels) == 1 && linitial(node->lockedRels) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11806,7 +11778,7 @@ _fingerprintWithClause(FingerprintContext *ctx, const WithClause *node, const vo hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ctes, node, "ctes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ctes) == 1 && linitial(node->ctes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11839,7 +11811,7 @@ _fingerprintInferClause(FingerprintContext *ctx, const InferClause *node, const hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->indexElems, node, "indexElems", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->indexElems) == 1 && linitial(node->indexElems) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11903,7 +11875,7 @@ _fingerprintOnConflictClause(FingerprintContext *ctx, const OnConflictClause *no hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->targetList, node, "targetList", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->targetList) == 1 && linitial(node->targetList) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11941,7 +11913,7 @@ _fingerprintCommonTableExpr(FingerprintContext *ctx, const CommonTableExpr *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->aliascolnames, node, "aliascolnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->aliascolnames) == 1 && linitial(node->aliascolnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11957,7 +11929,7 @@ _fingerprintCommonTableExpr(FingerprintContext *ctx, const CommonTableExpr *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ctecolcollations, node, "ctecolcollations", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ctecolcollations) == 1 && linitial(node->ctecolcollations) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11973,7 +11945,7 @@ _fingerprintCommonTableExpr(FingerprintContext *ctx, const CommonTableExpr *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ctecolnames, node, "ctecolnames", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ctecolnames) == 1 && linitial(node->ctecolnames) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -11989,7 +11961,7 @@ _fingerprintCommonTableExpr(FingerprintContext *ctx, const CommonTableExpr *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ctecoltypes, node, "ctecoltypes", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ctecoltypes) == 1 && linitial(node->ctecoltypes) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12005,7 +11977,7 @@ _fingerprintCommonTableExpr(FingerprintContext *ctx, const CommonTableExpr *node hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->ctecoltypmods, node, "ctecoltypmods", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->ctecoltypmods) == 1 && linitial(node->ctecoltypmods) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12104,7 +12076,7 @@ _fingerprintPartitionElem(FingerprintContext *ctx, const PartitionElem *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->collation, node, "collation", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->collation) == 1 && linitial(node->collation) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12144,7 +12116,7 @@ _fingerprintPartitionElem(FingerprintContext *ctx, const PartitionElem *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->opclass, node, "opclass", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->opclass) == 1 && linitial(node->opclass) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12167,7 +12139,7 @@ _fingerprintPartitionSpec(FingerprintContext *ctx, const PartitionSpec *node, co hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->partParams, node, "partParams", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->partParams) == 1 && linitial(node->partParams) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12198,7 +12170,7 @@ _fingerprintPartitionBoundSpec(FingerprintContext *ctx, const PartitionBoundSpec hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->listdatums, node, "listdatums", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->listdatums) == 1 && linitial(node->listdatums) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12216,7 +12188,7 @@ _fingerprintPartitionBoundSpec(FingerprintContext *ctx, const PartitionBoundSpec hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->lowerdatums, node, "lowerdatums", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->lowerdatums) == 1 && linitial(node->lowerdatums) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12252,7 +12224,7 @@ _fingerprintPartitionBoundSpec(FingerprintContext *ctx, const PartitionBoundSpec hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->upperdatums, node, "upperdatums", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->upperdatums) == 1 && linitial(node->upperdatums) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); @@ -12365,7 +12337,7 @@ _fingerprintVacuumRelation(FingerprintContext *ctx, const VacuumRelation *node, hash = XXH3_64bits_digest(ctx->xxh_state); _fingerprintNode(ctx, node->va_cols, node, "va_cols", depth + 1); - if (hash == XXH3_64bits_digest(ctx->xxh_state)) { + if (hash == XXH3_64bits_digest(ctx->xxh_state) && !(list_length(node->va_cols) == 1 && linitial(node->va_cols) == NIL)) { XXH3_copyState(ctx->xxh_state, prev); if (ctx->write_tokens) dlist_delete(dlist_tail_node(&ctx->tokens)); diff --git a/ext/pg_query/include/pg_query_outfuncs_defs.c b/ext/pg_query/include/pg_query_outfuncs_defs.c index 494a1128..f7000af6 100644 --- a/ext/pg_query/include/pg_query_outfuncs_defs.c +++ b/ext/pg_query/include/pg_query_outfuncs_defs.c @@ -897,6 +897,7 @@ _outAlterTableCmd(OUT_TYPE(AlterTableCmd, AlterTableCmd) out, const AlterTableCm WRITE_NODE_PTR_FIELD(def, def, def); WRITE_ENUM_FIELD(DropBehavior, behavior, behavior, behavior); WRITE_BOOL_FIELD(missing_ok, missing_ok, missing_ok); + WRITE_BOOL_FIELD(recurse, recurse, recurse); } static void diff --git a/ext/pg_query/include/pg_query_readfuncs_defs.c b/ext/pg_query/include/pg_query_readfuncs_defs.c index 5571dd6d..cc06747a 100644 --- a/ext/pg_query/include/pg_query_readfuncs_defs.c +++ b/ext/pg_query/include/pg_query_readfuncs_defs.c @@ -1014,6 +1014,7 @@ _readAlterTableCmd(OUT_TYPE(AlterTableCmd, AlterTableCmd) msg) READ_NODE_PTR_FIELD(def, def, def); READ_ENUM_FIELD(DropBehavior, behavior, behavior, behavior); READ_BOOL_FIELD(missing_ok, missing_ok, missing_ok); + READ_BOOL_FIELD(recurse, recurse, recurse); return node; } diff --git a/ext/pg_query/include/pgstat.h b/ext/pg_query/include/pgstat.h index c55dc148..46fa42c2 100644 --- a/ext/pg_query/include/pgstat.h +++ b/ext/pg_query/include/pgstat.h @@ -902,7 +902,8 @@ typedef enum WAIT_EVENT_PG_SLEEP, WAIT_EVENT_RECOVERY_APPLY_DELAY, WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL, - WAIT_EVENT_VACUUM_DELAY + WAIT_EVENT_VACUUM_DELAY, + WAIT_EVENT_REGISTER_SYNC_REQUEST } WaitEventTimeout; /* ---------- diff --git a/ext/pg_query/include/plpgsql.h b/ext/pg_query/include/plpgsql.h index 81a0dca7..87593cdc 100644 --- a/ext/pg_query/include/plpgsql.h +++ b/ext/pg_query/include/plpgsql.h @@ -919,10 +919,10 @@ typedef struct PLpgSQL_stmt_execsql int lineno; unsigned int stmtid; PLpgSQL_expr *sqlstmt; - bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note: - * mod_stmt is set when we plan the query */ + bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? */ bool into; /* INTO supplied? */ bool strict; /* INTO STRICT flag */ + bool mod_stmt_set; /* is mod_stmt valid yet? */ PLpgSQL_variable *target; /* INTO target (record or row) */ } PLpgSQL_stmt_execsql; diff --git a/ext/pg_query/include/port.h b/ext/pg_query/include/port.h index 271ff0d0..d4c94a44 100644 --- a/ext/pg_query/include/port.h +++ b/ext/pg_query/include/port.h @@ -429,6 +429,10 @@ extern size_t strnlen(const char *str, size_t maxlen); extern long random(void); #endif +#ifndef HAVE_SETENV +extern int setenv(const char *name, const char *value, int overwrite); +#endif + #ifndef HAVE_UNSETENV extern void unsetenv(const char *name); #endif diff --git a/ext/pg_query/include/port/pg_bitutils.h b/ext/pg_query/include/port/pg_bitutils.h index 887e7829..77fe42c6 100644 --- a/ext/pg_query/include/port/pg_bitutils.h +++ b/ext/pg_query/include/port/pg_bitutils.h @@ -137,7 +137,7 @@ pg_rightmost_one_pos64(uint64 word) /* * pg_nextpower2_32 - * Returns the next highest power of 2 of 'num', or 'num', if it's + * Returns the next higher power of 2 above 'num', or 'num' if it's * already a power of 2. * * 'num' mustn't be 0 or be above PG_UINT32_MAX / 2 + 1. @@ -160,7 +160,7 @@ pg_nextpower2_32(uint32 num) /* * pg_nextpower2_64 - * Returns the next highest power of 2 of 'num', or 'num', if it's + * Returns the next higher power of 2 above 'num', or 'num' if it's * already a power of 2. * * 'num' mustn't be 0 or be above PG_UINT64_MAX / 2 + 1. @@ -181,6 +181,52 @@ pg_nextpower2_64(uint64 num) return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1); } +/* + * pg_nextpower2_size_t + * Returns the next higher power of 2 above 'num', for a size_t input. + */ +#if SIZEOF_SIZE_T == 4 +#define pg_nextpower2_size_t(num) pg_nextpower2_32(num) +#else +#define pg_nextpower2_size_t(num) pg_nextpower2_64(num) +#endif + +/* + * pg_prevpower2_32 + * Returns the next lower power of 2 below 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0. + */ +static inline uint32 +pg_prevpower2_32(uint32 num) +{ + return ((uint32) 1) << pg_leftmost_one_pos32(num); +} + +/* + * pg_prevpower2_64 + * Returns the next lower power of 2 below 'num', or 'num' if it's + * already a power of 2. + * + * 'num' mustn't be 0. + */ +static inline uint64 +pg_prevpower2_64(uint64 num) +{ + return ((uint64) 1) << pg_leftmost_one_pos64(num); +} + +/* + * pg_prevpower2_size_t + * Returns the next lower power of 2 below 'num', for a size_t input. + */ +#if SIZEOF_SIZE_T == 4 +#define pg_prevpower2_size_t(num) pg_prevpower2_32(num) +#else +#define pg_prevpower2_size_t(num) pg_prevpower2_64(num) +#endif + /* * pg_ceil_log2_32 * Returns equivalent of ceil(log2(num)) diff --git a/ext/pg_query/include/protobuf/pg_query.pb-c.h b/ext/pg_query/include/protobuf/pg_query.pb-c.h index 3b9b4b15..85e13479 100644 --- a/ext/pg_query/include/protobuf/pg_query.pb-c.h +++ b/ext/pg_query/include/protobuf/pg_query.pb-c.h @@ -10,7 +10,7 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -1268,7 +1268,7 @@ typedef enum _PgQuery__Token { PG_QUERY__TOKEN__REASSIGN = 579, PG_QUERY__TOKEN__RECHECK = 580, PG_QUERY__TOKEN__RECURSIVE = 581, - PG_QUERY__TOKEN__REF = 582, + PG_QUERY__TOKEN__REF_P = 582, PG_QUERY__TOKEN__REFERENCES = 583, PG_QUERY__TOKEN__REFERENCING = 584, PG_QUERY__TOKEN__REFRESH = 585, @@ -3047,10 +3047,11 @@ struct PgQuery__AlterTableCmd PgQuery__Node *def; PgQuery__DropBehavior behavior; protobuf_c_boolean missing_ok; + protobuf_c_boolean recurse; }; #define PG_QUERY__ALTER_TABLE_CMD__INIT \ { PROTOBUF_C_MESSAGE_INIT (&pg_query__alter_table_cmd__descriptor) \ - , PG_QUERY__ALTER_TABLE_TYPE__ALTER_TABLE_TYPE_UNDEFINED, (char *)protobuf_c_empty_string, 0, NULL, NULL, PG_QUERY__DROP_BEHAVIOR__DROP_BEHAVIOR_UNDEFINED, 0 } + , PG_QUERY__ALTER_TABLE_TYPE__ALTER_TABLE_TYPE_UNDEFINED, (char *)protobuf_c_empty_string, 0, NULL, NULL, PG_QUERY__DROP_BEHAVIOR__DROP_BEHAVIOR_UNDEFINED, 0, 0 } struct PgQuery__AlterDomainStmt diff --git a/ext/pg_query/include/replication/reorderbuffer.h b/ext/pg_query/include/replication/reorderbuffer.h index 019bd382..5347597e 100644 --- a/ext/pg_query/include/replication/reorderbuffer.h +++ b/ext/pg_query/include/replication/reorderbuffer.h @@ -46,10 +46,10 @@ typedef struct ReorderBufferTupleBuf * changes. Users of the decoding facilities will never see changes with * *_INTERNAL_* actions. * - * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM changes concern - * "speculative insertions", and their confirmation respectively. They're - * used by INSERT .. ON CONFLICT .. UPDATE. Users of logical decoding don't - * have to care about these. + * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM, and INTERNAL_SPEC_ABORT + * changes concern "speculative insertions", their confirmation, and abort + * respectively. They're used by INSERT .. ON CONFLICT .. UPDATE. Users of + * logical decoding don't have to care about these. */ enum ReorderBufferChangeType { @@ -62,7 +62,8 @@ enum ReorderBufferChangeType REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID, REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT, REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM, - REORDER_BUFFER_CHANGE_TRUNCATE + REORDER_BUFFER_CHANGE_TRUNCATE, + REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT }; /* forward declaration */ diff --git a/ext/pg_query/include/replication/slot.h b/ext/pg_query/include/replication/slot.h index 31362585..12c68ddb 100644 --- a/ext/pg_query/include/replication/slot.h +++ b/ext/pg_query/include/replication/slot.h @@ -209,7 +209,7 @@ extern void ReplicationSlotsComputeRequiredLSN(void); extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void); extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive); extern void ReplicationSlotsDropDBSlots(Oid dboid); -extern void InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno); +extern bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno); extern void StartupReplicationSlots(void); extern void CheckPointReplicationSlots(void); diff --git a/ext/pg_query/include/storage/block.h b/ext/pg_query/include/storage/block.h index d73e3930..a87039bf 100644 --- a/ext/pg_query/include/storage/block.h +++ b/ext/pg_query/include/storage/block.h @@ -115,7 +115,7 @@ typedef BlockIdData *BlockId; /* block identifier */ #define BlockIdGetBlockNumber(blockId) \ ( \ AssertMacro(BlockIdIsValid(blockId)), \ - (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) \ + ((((BlockNumber) (blockId)->bi_hi) << 16) | ((BlockNumber) (blockId)->bi_lo)) \ ) #endif /* BLOCK_H */ diff --git a/ext/pg_query/include/storage/lock.h b/ext/pg_query/include/storage/lock.h index 2987c5e4..ab42f6b0 100644 --- a/ext/pg_query/include/storage/lock.h +++ b/ext/pg_query/include/storage/lock.h @@ -46,10 +46,11 @@ extern bool Debug_deadlocks; /* * Top-level transactions are identified by VirtualTransactionIDs comprising - * PGPROC fields backendId and lxid. For prepared transactions, the - * LocalTransactionId is an ordinary XID. These are guaranteed unique over - * the short term, but will be reused after a database restart or XID - * wraparound; hence they should never be stored on disk. + * PGPROC fields backendId and lxid. For recovered prepared transactions, the + * LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never + * refers to that kind. These are guaranteed unique over the short term, but + * will be reused after a database restart or XID wraparound; hence they + * should never be stored on disk. * * Note that struct VirtualTransactionId can not be assumed to be atomically * assignable as a whole. However, type LocalTransactionId is assumed to @@ -69,7 +70,7 @@ typedef struct #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId) #define VirtualTransactionIdIsValid(vxid) \ (LocalTransactionIdIsValid((vxid).localTransactionId)) -#define VirtualTransactionIdIsPreparedXact(vxid) \ +#define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \ ((vxid).backendId == InvalidBackendId) #define VirtualTransactionIdEquals(vxid1, vxid2) \ ((vxid1).backendId == (vxid2).backendId && \ diff --git a/ext/pg_query/include/storage/lwlock.h b/ext/pg_query/include/storage/lwlock.h index c04ae971..cdbfbed1 100644 --- a/ext/pg_query/include/storage/lwlock.h +++ b/ext/pg_query/include/storage/lwlock.h @@ -149,6 +149,7 @@ extern void LWLockRelease(LWLock *lock); extern void LWLockReleaseClearVar(LWLock *lock, uint64 *valptr, uint64 val); extern void LWLockReleaseAll(void); extern bool LWLockHeldByMe(LWLock *lock); +extern bool LWLockAnyHeldByMe(LWLock *lock, int nlocks, size_t stride); extern bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode); extern bool LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval); diff --git a/ext/pg_query/include/storage/proc.h b/ext/pg_query/include/storage/proc.h index 1ee9000b..7c85b564 100644 --- a/ext/pg_query/include/storage/proc.h +++ b/ext/pg_query/include/storage/proc.h @@ -62,6 +62,12 @@ struct XidCache #define PROC_VACUUM_STATE_MASK \ (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND) +/* + * Xmin-related flags. Make sure any flags that affect how the process' Xmin + * value is interpreted by VACUUM are included here. + */ +#define PROC_XMIN_FLAGS (PROC_IN_VACUUM) + /* * We allow a small number of "weak" relation locks (AccessShareLock, * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure @@ -76,6 +82,13 @@ struct XidCache */ #define INVALID_PGPROCNO PG_INT32_MAX +/* + * Flags used only for type of internal functions + * GetVirtualXIDsDelayingChkptGuts and HaveVirtualXIDsDelayingChkptGuts. + */ +#define DELAY_CHKPT_START (1<<0) +#define DELAY_CHKPT_COMPLETE (1<<1) + /* * Each backend has a PGPROC struct in shared memory. There is also a list of * currently-unused PGPROC structs that will be reallocated to new backends. @@ -143,6 +156,7 @@ struct PGPROC * lock object by this backend */ bool delayChkpt; /* true if this proc delays checkpoint start */ + bool delayChkptEnd; /* true if this proc delays checkpoint end */ /* * Info to allow us to wait for synchronous replication, if needed. diff --git a/ext/pg_query/include/storage/s_lock.h b/ext/pg_query/include/storage/s_lock.h index 31a5ca6f..6b368a5a 100644 --- a/ext/pg_query/include/storage/s_lock.h +++ b/ext/pg_query/include/storage/s_lock.h @@ -314,6 +314,7 @@ tas(volatile slock_t *lock) #endif /* __INTEL_COMPILER */ #endif /* __ia64__ || __ia64 */ + /* * On ARM and ARM64, we use __sync_lock_test_and_set(int *, int) if available. * @@ -340,6 +341,29 @@ tas(volatile slock_t *lock) #endif /* __arm__ || __arm || __aarch64__ || __aarch64 */ +/* + * RISC-V likewise uses __sync_lock_test_and_set(int *, int) if available. + */ +#if defined(__riscv) +#ifdef HAVE_GCC__SYNC_INT32_TAS +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef int slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#endif /* HAVE_GCC__SYNC_INT32_TAS */ +#endif /* __riscv */ + + /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) #define HAS_TEST_AND_SET diff --git a/ext/pg_query/include/tcop/pquery.h b/ext/pg_query/include/tcop/pquery.h index 437642cc..1385a007 100644 --- a/ext/pg_query/include/tcop/pquery.h +++ b/ext/pg_query/include/tcop/pquery.h @@ -17,6 +17,8 @@ #include "nodes/parsenodes.h" #include "utils/portal.h" +struct PlannedStmt; /* avoid including plannodes.h here */ + extern PGDLLIMPORT Portal ActivePortal; @@ -42,4 +44,8 @@ extern uint64 PortalRunFetch(Portal portal, long count, DestReceiver *dest); +extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt); + +extern void EnsurePortalSnapshotExists(void); + #endif /* PQUERY_H */ diff --git a/ext/pg_query/include/utils/builtins.h b/ext/pg_query/include/utils/builtins.h index 9519a3fa..8d7248dc 100644 --- a/ext/pg_query/include/utils/builtins.h +++ b/ext/pg_query/include/utils/builtins.h @@ -89,6 +89,7 @@ extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len); /* xid.c */ extern int xidComparator(const void *arg1, const void *arg2); +extern int xidLogicalComparator(const void *arg1, const void *arg2); /* inet_cidr_ntop.c */ extern char *pg_inet_cidr_ntop(int af, const void *src, int bits, diff --git a/ext/pg_query/include/utils/inval.h b/ext/pg_query/include/utils/inval.h index bc5081cf..4c6b86c9 100644 --- a/ext/pg_query/include/utils/inval.h +++ b/ext/pg_query/include/utils/inval.h @@ -61,4 +61,5 @@ extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, extern void CallSyscacheCallbacks(int cacheid, uint32 hashvalue); extern void InvalidateSystemCaches(void); +extern void InvalidateSystemCachesExtended(bool debug_discard); #endif /* INVAL_H */ diff --git a/ext/pg_query/include/utils/portal.h b/ext/pg_query/include/utils/portal.h index d41ff2ef..af0afcf9 100644 --- a/ext/pg_query/include/utils/portal.h +++ b/ext/pg_query/include/utils/portal.h @@ -194,6 +194,17 @@ typedef struct PortalData /* Presentation data, primarily used by the pg_cursors system view */ TimestampTz creation_time; /* time at which this portal was defined */ bool visible; /* include this portal in pg_cursors? */ + + /* Stuff added at the end to avoid ABI break in stable branches: */ + + /* + * Outermost ActiveSnapshot for execution of the portal's queries. For + * all but a few utility commands, we require such a snapshot to exist. + * This ensures that TOAST references in query results can be detoasted, + * and helps to reduce thrashing of the process's exposed xmin. + */ + Snapshot portalSnapshot; /* active snapshot, or NULL if none */ + int createLevel; /* creating subxact's nesting level */ } PortalData; /* @@ -211,6 +222,7 @@ extern void AtCleanup_Portals(void); extern void PortalErrorCleanup(void); extern void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, + int parentLevel, ResourceOwner parentXactOwner); extern void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, @@ -237,5 +249,6 @@ extern void PortalCreateHoldStore(Portal portal); extern void PortalHashTableDeleteAll(void); extern bool ThereAreNoReadyPortals(void); extern void HoldPinnedPortals(void); +extern void ForgetPortalSnapshots(void); #endif /* PORTAL_H */ diff --git a/ext/pg_query/include/utils/rel.h b/ext/pg_query/include/utils/rel.h index 0b5957ba..b7c10864 100644 --- a/ext/pg_query/include/utils/rel.h +++ b/ext/pg_query/include/utils/rel.h @@ -298,7 +298,6 @@ typedef struct StdRdOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ int fillfactor; /* page fill factor in percent (0..100) */ - /* fraction of newly inserted tuples prior to trigger index cleanup */ int toast_tuple_target; /* target for tuple toasting */ AutoVacOpts autovacuum; /* autovacuum-related options */ bool user_catalog_table; /* use as an additional catalog relation */ diff --git a/ext/pg_query/include/utils/relcache.h b/ext/pg_query/include/utils/relcache.h index 9a85b7dd..ff478c3b 100644 --- a/ext/pg_query/include/utils/relcache.h +++ b/ext/pg_query/include/utils/relcache.h @@ -14,7 +14,6 @@ #ifndef RELCACHE_H #define RELCACHE_H -#include "postgres.h" #include "access/tupdesc.h" #include "nodes/bitmapset.h" @@ -121,7 +120,7 @@ extern void RelationForgetRelation(Oid rid); extern void RelationCacheInvalidateEntry(Oid relationId); -extern void RelationCacheInvalidate(void); +extern void RelationCacheInvalidate(bool debug_discard); extern void RelationCloseSmgrByOid(Oid relationId); diff --git a/ext/pg_query/include/utils/snapmgr.h b/ext/pg_query/include/utils/snapmgr.h index ad7c15dc..651ff609 100644 --- a/ext/pg_query/include/utils/snapmgr.h +++ b/ext/pg_query/include/utils/snapmgr.h @@ -110,6 +110,7 @@ extern void InvalidateCatalogSnapshot(void); extern void InvalidateCatalogSnapshotConditionally(void); extern void PushActiveSnapshot(Snapshot snapshot); +extern void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level); extern void PushCopiedSnapshot(Snapshot snapshot); extern void UpdateActiveSnapshotCommandId(void); extern void PopActiveSnapshot(void); diff --git a/ext/pg_query/pg_query.pb-c.c b/ext/pg_query/pg_query.pb-c.c index 4a10d08c..5f8a2194 100644 --- a/ext/pg_query/pg_query.pb-c.c +++ b/ext/pg_query/pg_query.pb-c.c @@ -20686,7 +20686,7 @@ const ProtobufCMessageDescriptor pg_query__alter_table_stmt__descriptor = (ProtobufCMessageInit) pg_query__alter_table_stmt__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descriptors[7] = +static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descriptors[8] = { { "subtype", @@ -20772,6 +20772,18 @@ static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descripto 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "recurse", + 8, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(PgQuery__AlterTableCmd, recurse), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned pg_query__alter_table_cmd__field_indices_by_name[] = { 5, /* field[5] = behavior */ @@ -20780,12 +20792,13 @@ static const unsigned pg_query__alter_table_cmd__field_indices_by_name[] = { 1, /* field[1] = name */ 3, /* field[3] = newowner */ 2, /* field[2] = num */ + 7, /* field[7] = recurse */ 0, /* field[0] = subtype */ }; static const ProtobufCIntRange pg_query__alter_table_cmd__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 7 } + { 0, 8 } }; const ProtobufCMessageDescriptor pg_query__alter_table_cmd__descriptor = { @@ -20795,7 +20808,7 @@ const ProtobufCMessageDescriptor pg_query__alter_table_cmd__descriptor = "PgQuery__AlterTableCmd", "pg_query", sizeof(PgQuery__AlterTableCmd), - 7, + 8, pg_query__alter_table_cmd__field_descriptors, pg_query__alter_table_cmd__field_indices_by_name, 1, pg_query__alter_table_cmd__number_ranges, @@ -36975,7 +36988,7 @@ static const ProtobufCEnumValue pg_query__token__enum_values_by_number[494] = { "REASSIGN", "PG_QUERY__TOKEN__REASSIGN", 579 }, { "RECHECK", "PG_QUERY__TOKEN__RECHECK", 580 }, { "RECURSIVE", "PG_QUERY__TOKEN__RECURSIVE", 581 }, - { "REF", "PG_QUERY__TOKEN__REF", 582 }, + { "REF_P", "PG_QUERY__TOKEN__REF_P", 582 }, { "REFERENCES", "PG_QUERY__TOKEN__REFERENCES", 583 }, { "REFERENCING", "PG_QUERY__TOKEN__REFERENCING", 584 }, { "REFRESH", "PG_QUERY__TOKEN__REFRESH", 585 }, @@ -37472,10 +37485,10 @@ static const ProtobufCEnumValueIndex pg_query__token__enum_values_by_name[494] = { "REASSIGN", 341 }, { "RECHECK", 342 }, { "RECURSIVE", 343 }, - { "REF", 344 }, { "REFERENCES", 345 }, { "REFERENCING", 346 }, { "REFRESH", 347 }, + { "REF_P", 344 }, { "REINDEX", 348 }, { "RELATIVE_P", 349 }, { "RELEASE", 350 }, diff --git a/ext/pg_query/pg_query_deparse.c b/ext/pg_query/pg_query_deparse.c index 1a4dddbd..bd7d78ff 100644 --- a/ext/pg_query/pg_query_deparse.c +++ b/ext/pg_query/pg_query_deparse.c @@ -321,8 +321,7 @@ static void deparseExpr(StringInfo str, Node *node) deparseGroupingFunc(str, castNode(GroupingFunc, node)); break; default: - Assert(false); - elog(ERROR, "unpermitted node type in a_expr/b_expr: %d", + elog(ERROR, "deparse: unpermitted node type in a_expr/b_expr: %d", (int) nodeTag(node)); break; } @@ -372,8 +371,7 @@ static void deparseCExpr(StringInfo str, Node *node) deparseGroupingFunc(str, castNode(GroupingFunc, node)); break; default: - Assert(false); - elog(ERROR, "unpermitted node type in c_expr: %d", + elog(ERROR, "deparse: unpermitted node type in c_expr: %d", (int) nodeTag(node)); break; } @@ -1416,7 +1414,7 @@ static void deparseTargetList(StringInfo str, List *l) ResTarget *res_target = castNode(ResTarget, lfirst(lc)); if (res_target->val == NULL) - elog(ERROR, "deparse error in deparseTargetList: ResTarget without val"); + elog(ERROR, "deparse: error in deparseTargetList: ResTarget without val"); else if (IsA(res_target->val, ColumnRef)) deparseColumnRef(str, castNode(ColumnRef, res_target->val)); else @@ -2276,6 +2274,9 @@ static void deparseRangeVar(StringInfo str, RangeVar *range_var, DeparseNodeCont static void deparseRawStmt(StringInfo str, RawStmt *raw_stmt) { + if (raw_stmt->stmt == NULL) + elog(ERROR, "deparse error in deparseRawStmt: RawStmt with empty Stmt"); + deparseStmt(str, raw_stmt->stmt); } @@ -9427,7 +9428,7 @@ static void deparseValue(StringInfo str, Value *value, DeparseNodeContext contex appendStringInfoString(str, "NULL"); break; default: - elog(ERROR, "unrecognized value node type: %d", + elog(ERROR, "deparse: unrecognized value node type: %d", (int) nodeTag(value)); break; } @@ -9900,8 +9901,7 @@ static void deparseStmt(StringInfo str, Node *node) deparseCreateRangeStmt(str, castNode(CreateRangeStmt, node)); break; default: - // No other node types are supported at the top-level - Assert(false); + elog(ERROR, "deparse: unsupported top-level node type: %u", nodeTag(node)); } } diff --git a/ext/pg_query/pg_query_fingerprint.c b/ext/pg_query/pg_query_fingerprint.c index 0c520540..ac9d8952 100644 --- a/ext/pg_query/pg_query_fingerprint.c +++ b/ext/pg_query/pg_query_fingerprint.c @@ -374,6 +374,7 @@ void pg_query_free_fingerprint_result(PgQueryFingerprintResult result) if (result.error) { free(result.error->message); free(result.error->filename); + free(result.error->funcname); free(result.error); } diff --git a/ext/pg_query/pg_query_json_plpgsql.c b/ext/pg_query/pg_query_json_plpgsql.c index 71aa6f2f..8c122497 100644 --- a/ext/pg_query/pg_query_json_plpgsql.c +++ b/ext/pg_query/pg_query_json_plpgsql.c @@ -117,6 +117,7 @@ static void dump_return_next(StringInfo out, PLpgSQL_stmt_return_next *stmt); static void dump_return_query(StringInfo out, PLpgSQL_stmt_return_query *stmt); static void dump_raise(StringInfo out, PLpgSQL_stmt_raise *stmt); static void dump_raise_option(StringInfo out, PLpgSQL_raise_option *node); +static void dump_assert(StringInfo out, PLpgSQL_stmt_assert *stmt); static void dump_execsql(StringInfo out, PLpgSQL_stmt_execsql *stmt); static void dump_dynexecute(StringInfo out, PLpgSQL_stmt_dynexecute *stmt); static void dump_dynfors(StringInfo out, PLpgSQL_stmt_dynfors *stmt); @@ -126,6 +127,10 @@ static void dump_open(StringInfo out, PLpgSQL_stmt_open *stmt); static void dump_fetch(StringInfo out, PLpgSQL_stmt_fetch *stmt); static void dump_close(StringInfo out, PLpgSQL_stmt_close *stmt); static void dump_perform(StringInfo out, PLpgSQL_stmt_perform *stmt); +static void dump_call(StringInfo out, PLpgSQL_stmt_call *stmt); +static void dump_commit(StringInfo out, PLpgSQL_stmt_commit *stmt); +static void dump_rollback(StringInfo out, PLpgSQL_stmt_rollback *stmt); +static void dump_set(StringInfo out, PLpgSQL_stmt_set *stmt); static void dump_expr(StringInfo out, PLpgSQL_expr *expr); static void dump_function(StringInfo out, PLpgSQL_function *func); static void dump_exception(StringInfo out, PLpgSQL_exception *node); @@ -183,6 +188,9 @@ dump_stmt(StringInfo out, PLpgSQL_stmt *node) case PLPGSQL_STMT_RAISE: dump_raise(out, (PLpgSQL_stmt_raise *) node); break; + case PLPGSQL_STMT_ASSERT: + dump_assert(out, (PLpgSQL_stmt_assert *) node); + break; case PLPGSQL_STMT_EXECSQL: dump_execsql(out, (PLpgSQL_stmt_execsql *) node); break; @@ -207,6 +215,18 @@ dump_stmt(StringInfo out, PLpgSQL_stmt *node) case PLPGSQL_STMT_PERFORM: dump_perform(out, (PLpgSQL_stmt_perform *) node); break; + case PLPGSQL_STMT_CALL: + dump_call(out, (PLpgSQL_stmt_call *) node); + break; + case PLPGSQL_STMT_COMMIT: + dump_commit(out, (PLpgSQL_stmt_commit *) node); + break; + case PLPGSQL_STMT_ROLLBACK: + dump_rollback(out, (PLpgSQL_stmt_rollback *) node); + break; + case PLPGSQL_STMT_SET: + dump_set(out, (PLpgSQL_stmt_set *) node); + break; default: elog(ERROR, "unrecognized cmd_type: %d", node->cmd_type); break; @@ -444,6 +464,44 @@ dump_perform(StringInfo out, PLpgSQL_stmt_perform *node) WRITE_EXPR_FIELD(expr); } +static void +dump_call(StringInfo out, PLpgSQL_stmt_call *node) +{ + WRITE_NODE_TYPE("PLpgSQL_stmt_call"); + + WRITE_INT_FIELD(lineno, lineno, lineno); + WRITE_EXPR_FIELD(expr); + WRITE_BOOL_FIELD(is_call, is_call, is_call); + WRITE_VARIABLE_FIELD(target); +} + +static void +dump_commit(StringInfo out, PLpgSQL_stmt_commit *node) +{ + WRITE_NODE_TYPE("PLpgSQL_stmt_commit"); + + WRITE_INT_FIELD(lineno, lineno, lineno); + WRITE_BOOL_FIELD(chain, chain, chain); +} + +static void +dump_rollback(StringInfo out, PLpgSQL_stmt_rollback *node) +{ + WRITE_NODE_TYPE("PLpgSQL_stmt_rollback"); + + WRITE_INT_FIELD(lineno, lineno, lineno); + WRITE_BOOL_FIELD(chain, chain, chain); +} + +static void +dump_set(StringInfo out, PLpgSQL_stmt_set *node) +{ + WRITE_NODE_TYPE("PLpgSQL_stmt_set"); + + WRITE_INT_FIELD(lineno, lineno, lineno); + WRITE_EXPR_FIELD(expr); +} + static void dump_exit(StringInfo out, PLpgSQL_stmt_exit *node) { @@ -508,6 +566,16 @@ dump_raise_option(StringInfo out, PLpgSQL_raise_option *node) WRITE_EXPR_FIELD(expr); } +static void +dump_assert(StringInfo out, PLpgSQL_stmt_assert *node) +{ + WRITE_NODE_TYPE("PLpgSQL_stmt_assert"); + + WRITE_INT_FIELD(lineno, lineno, lineno); + WRITE_EXPR_FIELD(cond); + WRITE_EXPR_FIELD(message); +} + static void dump_execsql(StringInfo out, PLpgSQL_stmt_execsql *node) { diff --git a/ext/pg_query/pg_query_normalize.c b/ext/pg_query/pg_query_normalize.c index 5ac05cab..5e0e6778 100644 --- a/ext/pg_query/pg_query_normalize.c +++ b/ext/pg_query/pg_query_normalize.c @@ -8,6 +8,8 @@ #include "mb/pg_wchar.h" #include "nodes/nodeFuncs.h" +#include "pg_query_outfuncs.h" + /* * Struct for tracking locations/lengths of constants during normalization */ @@ -331,6 +333,27 @@ static void RecordConstLocation(pgssConstLocations *jstate, int location) } } +static void record_defelem_arg_location(pgssConstLocations *jstate, int location) +{ + for (int i = location; i < jstate->query_len; i++) { + if (jstate->query[i] == '\'' || jstate->query[i] == '$') { + RecordConstLocation(jstate, i); + break; + } + } +} + +static void record_matching_string(pgssConstLocations *jstate, const char *str) +{ + char *loc = NULL; + if (str == NULL) + return; + + loc = strstr(jstate->query, str); + if (loc != NULL) + RecordConstLocation(jstate, loc - jstate->query - 1); +} + static bool const_record_walker(Node *node, pgssConstLocations *jstate) { bool result; @@ -362,13 +385,12 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate) case T_DefElem: { DefElem * defElem = (DefElem *) node; - if (defElem->arg != NULL && IsA(defElem->arg, String)) { - for (int i = defElem->location; i < jstate->query_len; i++) { - if (jstate->query[i] == '\'') { - RecordConstLocation(jstate, i); - break; - } - } + if (defElem->arg == NULL) { + // No argument + } else if (IsA(defElem->arg, String)) { + record_defelem_arg_location(jstate, defElem->location); + } else if (IsA(defElem->arg, List) && list_length((List *) defElem->arg) == 1 && IsA(linitial((List *) defElem->arg), String)) { + record_defelem_arg_location(jstate, defElem->location); } return const_record_walker((Node *) ((DefElem *) node)->arg, jstate); } @@ -387,6 +409,20 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate) return const_record_walker((Node *) ((AlterRoleStmt *) node)->options, jstate); case T_DeclareCursorStmt: return const_record_walker((Node *) ((DeclareCursorStmt *) node)->query, jstate); + case T_CreateFunctionStmt: + return const_record_walker((Node *) ((CreateFunctionStmt *) node)->options, jstate); + case T_DoStmt: + return const_record_walker((Node *) ((DoStmt *) node)->args, jstate); + case T_CreateSubscriptionStmt: + record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo); + break; + case T_AlterSubscriptionStmt: + record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo); + break; + case T_CreateUserMappingStmt: + return const_record_walker((Node *) ((CreateUserMappingStmt *) node)->options, jstate); + case T_AlterUserMappingStmt: + return const_record_walker((Node *) ((AlterUserMappingStmt *) node)->options, jstate); case T_TypeName: /* Don't normalize constants in typmods or arrayBounds */ return false; diff --git a/ext/pg_query/pg_query_outfuncs.h b/ext/pg_query/pg_query_outfuncs.h index d1c61c31..bbd75b98 100644 --- a/ext/pg_query/pg_query_outfuncs.h +++ b/ext/pg_query/pg_query_outfuncs.h @@ -5,6 +5,7 @@ PgQueryProtobuf pg_query_nodes_to_protobuf(const void *obj); +char *pg_query_node_to_json(const void *obj); char *pg_query_nodes_to_json(const void *obj); #endif diff --git a/ext/pg_query/pg_query_outfuncs_json.c b/ext/pg_query/pg_query_outfuncs_json.c index 9051a7cb..ce375654 100644 --- a/ext/pg_query/pg_query_outfuncs_json.c +++ b/ext/pg_query/pg_query_outfuncs_json.c @@ -259,6 +259,17 @@ _outNode(StringInfo out, const void *obj) } } +char * +pg_query_node_to_json(const void *obj) +{ + StringInfoData out; + + initStringInfo(&out); + _outNode(&out, obj); + + return out.data; +} + char * pg_query_nodes_to_json(const void *obj) { diff --git a/ext/pg_query/pg_query_parse_plpgsql.c b/ext/pg_query/pg_query_parse_plpgsql.c index 9a1f8d43..8f37a20d 100644 --- a/ext/pg_query/pg_query_parse_plpgsql.c +++ b/ext/pg_query/pg_query_parse_plpgsql.c @@ -18,7 +18,7 @@ typedef struct { PgQueryError* error; } PgQueryInternalPlpgsqlFuncAndError; -static PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(CreateFunctionStmt* stmt); +static PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(Node* stmt); static void add_dummy_return(PLpgSQL_function *function) { @@ -73,6 +73,36 @@ static void plpgsql_compile_error_callback(void *arg) plpgsql_error_funcname, plpgsql_latest_lineno()); } +static PLpgSQL_function *compile_do_stmt(DoStmt* stmt) +{ + char *proc_source = NULL; + const ListCell *lc; + char *language = "plpgsql"; + + assert(IsA(stmt, DoStmt)); + + foreach(lc, stmt->args) + { + DefElem* elem = (DefElem*) lfirst(lc); + + if (strcmp(elem->defname, "as") == 0) { + + assert(IsA(elem->arg, String)); + proc_source = strVal(elem->arg); + } else if (strcmp(elem->defname, "language") == 0) { + language = strVal(elem->arg); + } + } + + assert(proc_source != NULL); + + if(strcmp(language, "plpgsql") != 0) { + return (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function)); + } + return plpgsql_compile_inline(proc_source); + +} + static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt) { char *func_name; @@ -87,6 +117,7 @@ static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt) const ListCell *lc, *lc2, *lc3; bool is_trigger = false; bool is_setof = false; + char *language = "plpgsql"; assert(IsA(stmt, CreateFunctionStmt)); @@ -105,11 +136,17 @@ static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt) { proc_source = strVal(lfirst(lc2)); } + } else if (strcmp(elem->defname, "language") == 0) { + language = strVal(elem->arg); } } assert(proc_source != NULL); + if(strcmp(language, "plpgsql") != 0) { + return (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function)); + } + if (stmt->returnType != NULL) { foreach(lc3, stmt->returnType->names) { @@ -273,7 +310,7 @@ static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt) return function; } -PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(CreateFunctionStmt* stmt) +PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(Node* stmt) { PgQueryInternalPlpgsqlFuncAndError result = {0}; MemoryContext cctx = CurrentMemoryContext; @@ -306,7 +343,13 @@ PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(CreateFunctionStmt PG_TRY(); { - result.func = compile_create_function_stmt(stmt); + if (IsA(stmt, CreateFunctionStmt)) { + result.func = compile_create_function_stmt((CreateFunctionStmt *) stmt); + } else if (IsA(stmt, DoStmt)){ + result.func = compile_do_stmt((DoStmt *) stmt); + } else { + elog(ERROR, "Unexpected node type for PL/pgSQL parsing: %d", nodeTag(stmt)); + } #ifndef DEBUG // Save stderr for result @@ -354,36 +397,36 @@ PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(CreateFunctionStmt return result; } -typedef struct createFunctionStmts +typedef struct plStmts { - CreateFunctionStmt **stmts; + Node **stmts; int stmts_buf_size; int stmts_count; -} createFunctionStmts; +} plStmts; -static bool create_function_stmts_walker(Node *node, createFunctionStmts *state) +static bool stmts_walker(Node *node, plStmts *state) { bool result; MemoryContext ccxt = CurrentMemoryContext; if (node == NULL) return false; - if (IsA(node, CreateFunctionStmt)) + if (IsA(node, CreateFunctionStmt) || IsA(node, DoStmt)) { if (state->stmts_count >= state->stmts_buf_size) { state->stmts_buf_size *= 2; - state->stmts = (CreateFunctionStmt**) repalloc(state->stmts, state->stmts_buf_size * sizeof(CreateFunctionStmt*)); + state->stmts = (Node**) repalloc(state->stmts, state->stmts_buf_size * sizeof(Node*)); } - state->stmts[state->stmts_count] = (CreateFunctionStmt *) node; + state->stmts[state->stmts_count] = (Node *) node; state->stmts_count++; } else if (IsA(node, RawStmt)) { - return create_function_stmts_walker((Node *) ((RawStmt *) node)->stmt, state); + return stmts_walker((Node *) ((RawStmt *) node)->stmt, state); } PG_TRY(); { - result = raw_expression_tree_walker(node, create_function_stmts_walker, (void*) state); + result = raw_expression_tree_walker(node, stmts_walker, (void*) state); } PG_CATCH(); { @@ -401,7 +444,7 @@ PgQueryPlpgsqlParseResult pg_query_parse_plpgsql(const char* input) MemoryContext ctx = NULL; PgQueryPlpgsqlParseResult result = {0}; PgQueryInternalParsetreeAndError parse_result; - createFunctionStmts statements; + plStmts statements; size_t i; ctx = pg_query_enter_memory_context(); @@ -414,10 +457,10 @@ PgQueryPlpgsqlParseResult pg_query_parse_plpgsql(const char* input) } statements.stmts_buf_size = 100; - statements.stmts = (CreateFunctionStmt**) palloc(statements.stmts_buf_size * sizeof(CreateFunctionStmt*)); + statements.stmts = (Node**) palloc(statements.stmts_buf_size * sizeof(Node*)); statements.stmts_count = 0; - create_function_stmts_walker((Node*) parse_result.tree, &statements); + stmts_walker((Node*) parse_result.tree, &statements); if (statements.stmts_count == 0) { result.plpgsql_funcs = strdup("[]"); diff --git a/ext/pg_query/src_backend_catalog_namespace.c b/ext/pg_query/src_backend_catalog_namespace.c index 2841ebf7..9c0f722c 100644 --- a/ext/pg_query/src_backend_catalog_namespace.c +++ b/ext/pg_query/src_backend_catalog_namespace.c @@ -62,6 +62,7 @@ #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/snapmgr.h" #include "utils/syscache.h" #include "utils/varlena.h" diff --git a/ext/pg_query/src_backend_libpq_pqcomm.c b/ext/pg_query/src_backend_libpq_pqcomm.c index 504bdf96..5be9b386 100644 --- a/ext/pg_query/src_backend_libpq_pqcomm.c +++ b/ext/pg_query/src_backend_libpq_pqcomm.c @@ -404,6 +404,14 @@ const PQcommMethods *PqCommMethods = NULL; */ +/* -------------------------------- + * pq_buffer_has_data - is any buffered data available to read? + * + * This will *not* attempt to read more data. + * -------------------------------- + */ + + /* -------------------------------- * pq_startmsgread - begin reading a message from the client. diff --git a/ext/pg_query/src_backend_nodes_copyfuncs.c b/ext/pg_query/src_backend_nodes_copyfuncs.c index 2a840848..7bad04f5 100644 --- a/ext/pg_query/src_backend_nodes_copyfuncs.c +++ b/ext/pg_query/src_backend_nodes_copyfuncs.c @@ -345,8 +345,11 @@ #define COPY_POINTER_FIELD(fldname, sz) \ do { \ Size _size = (sz); \ - newnode->fldname = palloc(_size); \ - memcpy(newnode->fldname, from->fldname, _size); \ + if (_size > 0) \ + { \ + newnode->fldname = palloc(_size); \ + memcpy(newnode->fldname, from->fldname, _size); \ + } \ } while (0) /* Copy a parse location field (for Copy, this is same as scalar case) */ @@ -584,12 +587,9 @@ _copyRecursiveUnion(const RecursiveUnion *from) */ COPY_SCALAR_FIELD(wtParam); COPY_SCALAR_FIELD(numCols); - if (from->numCols > 0) - { - COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); - COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid)); COPY_SCALAR_FIELD(numGroups); return newnode; @@ -803,6 +803,7 @@ _copyIndexOnlyScan(const IndexOnlyScan *from) */ COPY_SCALAR_FIELD(indexid); COPY_NODE_FIELD(indexqual); + COPY_NODE_FIELD(recheckqual); COPY_NODE_FIELD(indexorderby); COPY_NODE_FIELD(indextlist); COPY_SCALAR_FIELD(indexorderdir); @@ -1162,13 +1163,10 @@ _copyMergeJoin(const MergeJoin *from) COPY_SCALAR_FIELD(skip_mark_restore); COPY_NODE_FIELD(mergeclauses); numCols = list_length(from->mergeclauses); - if (numCols > 0) - { - COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid)); - COPY_POINTER_FIELD(mergeCollations, numCols * sizeof(Oid)); - COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int)); - COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool)); - } + COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid)); + COPY_POINTER_FIELD(mergeCollations, numCols * sizeof(Oid)); + COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int)); + COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool)); return newnode; } @@ -1303,12 +1301,9 @@ _copyAgg(const Agg *from) COPY_SCALAR_FIELD(aggstrategy); COPY_SCALAR_FIELD(aggsplit); COPY_SCALAR_FIELD(numCols); - if (from->numCols > 0) - { - COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); - COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid)); COPY_SCALAR_FIELD(numGroups); COPY_SCALAR_FIELD(transitionSpace); COPY_BITMAPSET_FIELD(aggParams); @@ -1330,19 +1325,13 @@ _copyWindowAgg(const WindowAgg *from) COPY_SCALAR_FIELD(winref); COPY_SCALAR_FIELD(partNumCols); - if (from->partNumCols > 0) - { - COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid)); - COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid)); COPY_SCALAR_FIELD(ordNumCols); - if (from->ordNumCols > 0) - { - COPY_POINTER_FIELD(ordColIdx, from->ordNumCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid)); - COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid)); - } + COPY_POINTER_FIELD(ordColIdx, from->ordNumCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid)); COPY_SCALAR_FIELD(frameOptions); COPY_NODE_FIELD(startOffset); COPY_NODE_FIELD(endOffset); @@ -3510,6 +3499,7 @@ _copyAlterTableCmd(const AlterTableCmd *from) COPY_NODE_FIELD(def); COPY_SCALAR_FIELD(behavior); COPY_SCALAR_FIELD(missing_ok); + COPY_SCALAR_FIELD(recurse); return newnode; } diff --git a/ext/pg_query/src_backend_nodes_equalfuncs.c b/ext/pg_query/src_backend_nodes_equalfuncs.c index 504ce290..c55de26c 100644 --- a/ext/pg_query/src_backend_nodes_equalfuncs.c +++ b/ext/pg_query/src_backend_nodes_equalfuncs.c @@ -1335,6 +1335,7 @@ _equalAlterTableCmd(const AlterTableCmd *a, const AlterTableCmd *b) COMPARE_NODE_FIELD(def); COMPARE_SCALAR_FIELD(behavior); COMPARE_SCALAR_FIELD(missing_ok); + COMPARE_SCALAR_FIELD(recurse); return true; } diff --git a/ext/pg_query/src_backend_nodes_list.c b/ext/pg_query/src_backend_nodes_list.c index e787561b..6943c8fb 100644 --- a/ext/pg_query/src_backend_nodes_list.c +++ b/ext/pg_query/src_backend_nodes_list.c @@ -642,6 +642,18 @@ list_delete_cell(List *list, ListCell *cell) */ +/* + * Delete the first N cells of the list. + * + * The List is pfree'd if the request causes all cells to be deleted. + */ +#ifndef DEBUG_LIST_MEMORY_USAGE +#else +#ifdef CLOBBER_FREED_MEMORY +#else +#endif +#endif + /* * Generate the union of two lists. This is calculated by copying * list1 via list_copy(), then adding to it all the members of list2 diff --git a/ext/pg_query/src_backend_parser_gram.c b/ext/pg_query/src_backend_parser_gram.c index 0b60f0ec..230204af 100644 --- a/ext/pg_query/src_backend_parser_gram.c +++ b/ext/pg_query/src_backend_parser_gram.c @@ -457,7 +457,7 @@ REASSIGN = 579, RECHECK = 580, RECURSIVE = 581, - REF = 582, + REF_P = 582, REFERENCES = 583, REFERENCING = 584, REFRESH = 585, @@ -934,7 +934,7 @@ #define REASSIGN 579 #define RECHECK 580 #define RECURSIVE 581 -#define REF 582 +#define REF_P 582 #define REFERENCES 583 #define REFERENCING 584 #define REFRESH 585 @@ -3354,7 +3354,7 @@ static const char *const yytname[] = "PRESERVE", "PREPARE", "PREPARED", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURAL", "PROCEDURE", "PROCEDURES", "PROGRAM", "PUBLICATION", "QUOTE", "RANGE", "READ", "REAL", "REASSIGN", "RECHECK", "RECURSIVE", - "REF", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P", + "REF_P", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P", "RELEASE", "RENAME", "REPEATABLE", "REPLACE", "REPLICA", "RESET", "RESTART", "RESTRICT", "RETURNING", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUTINE", "ROUTINES", "ROW", "ROWS", "RULE", @@ -46994,6 +46994,21 @@ insertSelectOptions(SelectStmt *stmt, ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("WITH TIES cannot be specified without ORDER BY clause"))); + if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause) + { + ListCell *lc; + + foreach(lc, stmt->lockingClause) + { + LockingClause *lock = lfirst_node(LockingClause, lc); + + if (lock->waitPolicy == LockWaitSkip) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s and %s options cannot be used together", + "SKIP LOCKED", "WITH TIES"))); + } + } stmt->limitOption = limitClause->limitOption; } if (withClause) diff --git a/ext/pg_query/src_backend_parser_scan.c b/ext/pg_query/src_backend_parser_scan.c index f543142e..33ea1fdb 100644 --- a/ext/pg_query/src_backend_parser_scan.c +++ b/ext/pg_query/src_backend_parser_scan.c @@ -43,8 +43,7 @@ *-------------------------------------------------------------------- */ -#line 2 "scan.c" -#line 2 "scan.l" +#line 1 "scan.c" /*------------------------------------------------------------------------- * * scan.l @@ -87,9 +86,7 @@ #include "parser/scansup.h" #include "mb/pg_wchar.h" - - -#line 48 "scan.c" +#line 44 "scan.c" #define YY_INT_ALIGNED short int @@ -97,12 +94,246 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif +#ifdef yy_create_buffer +#define core_yy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer core_yy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define core_yy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer core_yy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define core_yy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer core_yy_scan_buffer +#endif + +#ifdef yy_scan_string +#define core_yy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string core_yy_scan_string +#endif + +#ifdef yy_scan_bytes +#define core_yy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes core_yy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define core_yy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer core_yy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define core_yy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer core_yy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define core_yy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state core_yy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define core_yy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer core_yy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define core_yypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state core_yypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define core_yypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state core_yypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define core_yyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack core_yyensure_buffer_stack +#endif + +#ifdef yylex +#define core_yylex_ALREADY_DEFINED +#else +#define yylex core_yylex +#endif + +#ifdef yyrestart +#define core_yyrestart_ALREADY_DEFINED +#else +#define yyrestart core_yyrestart +#endif + +#ifdef yylex_init +#define core_yylex_init_ALREADY_DEFINED +#else +#define yylex_init core_yylex_init +#endif + +#ifdef yylex_init_extra +#define core_yylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra core_yylex_init_extra +#endif + +#ifdef yylex_destroy +#define core_yylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy core_yylex_destroy +#endif + +#ifdef yyget_debug +#define core_yyget_debug_ALREADY_DEFINED +#else +#define yyget_debug core_yyget_debug +#endif + +#ifdef yyset_debug +#define core_yyset_debug_ALREADY_DEFINED +#else +#define yyset_debug core_yyset_debug +#endif + +#ifdef yyget_extra +#define core_yyget_extra_ALREADY_DEFINED +#else +#define yyget_extra core_yyget_extra +#endif + +#ifdef yyset_extra +#define core_yyset_extra_ALREADY_DEFINED +#else +#define yyset_extra core_yyset_extra +#endif + +#ifdef yyget_in +#define core_yyget_in_ALREADY_DEFINED +#else +#define yyget_in core_yyget_in +#endif + +#ifdef yyset_in +#define core_yyset_in_ALREADY_DEFINED +#else +#define yyset_in core_yyset_in +#endif + +#ifdef yyget_out +#define core_yyget_out_ALREADY_DEFINED +#else +#define yyget_out core_yyget_out +#endif + +#ifdef yyset_out +#define core_yyset_out_ALREADY_DEFINED +#else +#define yyset_out core_yyset_out +#endif + +#ifdef yyget_leng +#define core_yyget_leng_ALREADY_DEFINED +#else +#define yyget_leng core_yyget_leng +#endif + +#ifdef yyget_text +#define core_yyget_text_ALREADY_DEFINED +#else +#define yyget_text core_yyget_text +#endif + +#ifdef yyget_lineno +#define core_yyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno core_yyget_lineno +#endif + +#ifdef yyset_lineno +#define core_yyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno core_yyset_lineno +#endif + +#ifdef yyget_column +#define core_yyget_column_ALREADY_DEFINED +#else +#define yyget_column core_yyget_column +#endif + +#ifdef yyset_column +#define core_yyset_column_ALREADY_DEFINED +#else +#define yyset_column core_yyset_column +#endif + +#ifdef yywrap +#define core_yywrap_ALREADY_DEFINED +#else +#define yywrap core_yywrap +#endif + +#ifdef yyget_lval +#define core_yyget_lval_ALREADY_DEFINED +#else +#define yyget_lval core_yyget_lval +#endif + +#ifdef yyset_lval +#define core_yyset_lval_ALREADY_DEFINED +#else +#define yyset_lval core_yyset_lval +#endif + +#ifdef yyget_lloc +#define core_yyget_lloc_ALREADY_DEFINED +#else +#define yyget_lloc core_yyget_lloc +#endif + +#ifdef yyset_lloc +#define core_yyset_lloc_ALREADY_DEFINED +#else +#define yyset_lloc core_yyset_lloc +#endif + +#ifdef yyalloc +#define core_yyalloc_ALREADY_DEFINED +#else +#define yyalloc core_yyalloc +#endif + +#ifdef yyrealloc +#define core_yyrealloc_ALREADY_DEFINED +#else +#define yyrealloc core_yyrealloc +#endif + +#ifdef yyfree +#define core_yyfree_ALREADY_DEFINED +#else +#define yyfree core_yyfree +#endif + /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ @@ -144,7 +375,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -175,38 +405,32 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) +#endif /* ! C99 */ -#define YY_USE_CONST +#endif /* ! FLEXINT_H */ -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ +/* begin standard C++ headers. */ -#ifdef YY_USE_CONST +/* TODO: this is always defined, so inline it */ #define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) #else -#define yyconst +#define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -230,25 +454,29 @@ typedef void* yyscan_t; * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * - /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START - /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - /* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE core_yyrestart(yyin ,yyscanner ) - +#define YY_NEW_FILE yyrestart( yyin , yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -268,8 +496,9 @@ typedef size_t yy_size_t; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -284,7 +513,6 @@ typedef size_t yy_size_t; YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) - #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_STRUCT_YY_BUFFER_STATE @@ -299,7 +527,7 @@ struct yy_buffer_state /* Size of input buffer in bytes, not including room for EOB * characters. */ - yy_size_t yy_buf_size; + int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. @@ -327,7 +555,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -344,7 +572,7 @@ struct yy_buffer_state * possible backing-up. * * When we actually see the EOF, we change the status to "new" - * (via core_yyrestart()), so that the user can continue scanning by + * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 @@ -361,73 +589,67 @@ struct yy_buffer_state #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) - /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] -void core_yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void core_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void core_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void core_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void core_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void core_yypop_buffer_state (yyscan_t yyscanner ); +void yyrestart ( FILE *input_file , yyscan_t yyscanner ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); +void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +void yypop_buffer_state ( yyscan_t yyscanner ); -static void core_yyensure_buffer_stack (yyscan_t yyscanner ); -static void core_yy_load_buffer_state (yyscan_t yyscanner ); -static void core_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); +static void yyensure_buffer_stack ( yyscan_t yyscanner ); +static void yy_load_buffer_state ( yyscan_t yyscanner ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) -#define YY_FLUSH_BUFFER core_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len , yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *core_yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *core_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void core_yyfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer core_yy_create_buffer +void *yyalloc ( yy_size_t , yyscan_t yyscanner ); +void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); +void yyfree ( void * , yyscan_t yyscanner ); +#define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ - core_yyensure_buffer_stack (yyscanner); \ + yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } - #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ - core_yyensure_buffer_stack (yyscanner); \ + yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } - #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ -#define core_yywrap(n) 1 +#define core_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; -typedef unsigned char YY_CHAR; - -typedef yyconst struct yy_trans_info *yy_state_type; +typedef const struct yy_trans_info *yy_state_type; #define yytext_ptr yytext_r -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); +static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); +static int yy_get_next_buffer ( yyscan_t yyscanner ); +static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. @@ -438,7 +660,6 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; - #define YY_NUM_RULES 66 #define YY_END_OF_BUFFER 67 struct yy_trans_info @@ -446,7 +667,7 @@ struct yy_trans_info flex_int16_t yy_verify; flex_int16_t yy_nxt; }; -static yyconst struct yy_trans_info yy_transition[17678] = +static const struct yy_trans_info yy_transition[17678] = { { 0, 0 }, { 0,17422 }, { 0, 0 }, { 0,17420 }, { 1,6192 }, { 2,6192 }, { 3,6192 }, { 4,6192 }, { 5,6192 }, { 6,6192 }, @@ -4282,7 +4503,7 @@ static yyconst struct yy_trans_info yy_transition[17678] = { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 257, 67 }, { 1, 0 }, }; -static __thread yyconst struct yy_trans_info *yy_start_state_list[25] = +static __thread const struct yy_trans_info *yy_start_state_list[25] = { &yy_transition[1], &yy_transition[3], @@ -4376,7 +4597,7 @@ const uint16 ScanKeywordTokens[] = { #define YY_EXTRA_TYPE core_yy_extra_type * /* - * Each call to core_yylex must set yylloc to the location of the found token + * Each call to yylex must set yylloc to the location of the found token * (expressed as a byte offset from the start of the input text). * When we parse a token that requires multiple lexer rules to process, * this should be done in the first such rule, else yylloc will point @@ -4425,6 +4646,7 @@ static void check_escape_warning(core_yyscan_t yyscanner); extern int core_yyget_column(yyscan_t yyscanner); extern void core_yyset_column(int column_no, yyscan_t yyscanner); +#line 4600 "scan.c" #define YY_NO_INPUT 1 /* * OK, here is a short description of lex/flex rules behavior. @@ -4453,16 +4675,6 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); * The default one is probably not the right thing. */ - - - - - - - - - - /* * In order to make the world safe for Windows and Mac clients as well as * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n @@ -4583,7 +4795,7 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); * Note that xcstart must appear before operator, as explained above! * Also whitespace (comment) must appear before operator. */ -#line 4538 "scan.c" +#line 4749 "scan.c" #define INITIAL 0 #define xb 1 @@ -4648,7 +4860,7 @@ struct yyguts_t }; /* end struct yyguts_t */ -static int yy_init_globals (yyscan_t yyscanner ); +static int yy_init_globals ( yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ @@ -4656,46 +4868,50 @@ static int yy_init_globals (yyscan_t yyscanner ); # define yylloc yyg->yylloc_r -int core_yylex_init (yyscan_t* scanner); +int yylex_init (yyscan_t* scanner); -int core_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); +int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ -int core_yylex_destroy (yyscan_t yyscanner ); +int yylex_destroy ( yyscan_t yyscanner ); + +int yyget_debug ( yyscan_t yyscanner ); + +void yyset_debug ( int debug_flag , yyscan_t yyscanner ); -int core_yyget_debug (yyscan_t yyscanner ); +YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); -void core_yyset_debug (int debug_flag ,yyscan_t yyscanner ); +void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); -YY_EXTRA_TYPE core_yyget_extra (yyscan_t yyscanner ); +FILE *yyget_in ( yyscan_t yyscanner ); -void core_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); +void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); -FILE *core_yyget_in (yyscan_t yyscanner ); +FILE *yyget_out ( yyscan_t yyscanner ); -void core_yyset_in (FILE * in_str ,yyscan_t yyscanner ); +void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); -FILE *core_yyget_out (yyscan_t yyscanner ); + yy_size_t yyget_leng ( yyscan_t yyscanner ); -void core_yyset_out (FILE * out_str ,yyscan_t yyscanner ); +char *yyget_text ( yyscan_t yyscanner ); -yy_size_t core_yyget_leng (yyscan_t yyscanner ); +int yyget_lineno ( yyscan_t yyscanner ); -char *core_yyget_text (yyscan_t yyscanner ); +void yyset_lineno ( int _line_number , yyscan_t yyscanner ); -int core_yyget_lineno (yyscan_t yyscanner ); +int yyget_column ( yyscan_t yyscanner ); -void core_yyset_lineno (int line_number ,yyscan_t yyscanner ); +void yyset_column ( int _column_no , yyscan_t yyscanner ); -YYSTYPE * core_yyget_lval (yyscan_t yyscanner ); +YYSTYPE * yyget_lval ( yyscan_t yyscanner ); -void core_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); +void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); - YYLTYPE *core_yyget_lloc (yyscan_t yyscanner ); + YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); - void core_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -4703,33 +4919,41 @@ void core_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus -extern "C" int core_yywrap (yyscan_t yyscanner ); +extern "C" int yywrap ( yyscan_t yyscanner ); #else -extern int core_yywrap (yyscan_t yyscanner ); +extern int yywrap ( yyscan_t yyscanner ); #endif #endif +#ifndef YY_NO_UNPUT + +#endif + #ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +static int yy_flex_strlen ( const char * , yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT - #ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); +static int yyinput ( yyscan_t yyscanner ); #else -static int input (yyscan_t yyscanner ); +static int input ( yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -4737,7 +4961,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -4761,7 +4985,7 @@ static int input (yyscan_t yyscanner ); else \ { \ errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ @@ -4802,10 +5026,10 @@ static int input (yyscan_t yyscanner ); #ifndef YY_DECL #define YY_DECL_IS_OURS 1 -extern int core_yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); +extern int yylex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); -#define YY_DECL int core_yylex \ +#define YY_DECL int yylex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ @@ -4818,7 +5042,7 @@ extern int core_yylex \ /* Code executed at the end of each rule. */ #ifndef YY_BREAK -#define YY_BREAK break; +#define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ @@ -4828,16 +5052,11 @@ extern int core_yylex \ */ YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 420 "scan.l" - - -#line 4791 "scan.c" - yylval = yylval_param; yylloc = yylloc_param; @@ -4860,15 +5079,21 @@ YY_DECL yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { - core_yyensure_buffer_stack (yyscanner); + yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } - core_yy_load_buffer_state(yyscanner ); + yy_load_buffer_state( yyscanner ); } - while ( 1 ) /* loops until end-of-file is reached */ + { +#line 420 "scan.l" + + +#line 5045 "scan.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; @@ -4883,12 +5108,12 @@ YY_DECL yy_current_state = yy_start_state_list[yyg->yy_start]; yy_match: { - register yyconst struct yy_trans_info *yy_trans_info; + const struct yy_trans_info *yy_trans_info; - register YY_CHAR yy_c; + YY_CHAR yy_c; for ( yy_c = YY_SC_TO_UI(*yy_cp); - (yy_trans_info = &yy_current_state[(unsigned int) yy_c])-> + (yy_trans_info = &yy_current_state[yy_c])-> yy_verify == yy_c; yy_c = YY_SC_TO_UI(*++yy_cp) ) yy_current_state += yy_trans_info->yy_nxt; @@ -5140,6 +5365,7 @@ case 19: case 20: /* rule 20 can match eol */ #line 585 "scan.l" +YY_RULE_SETUP case YY_STATE_EOF(xqs): #line 585 "scan.l" { @@ -5267,6 +5493,7 @@ case 26: case 27: /* rule 27 can match eol */ #line 685 "scan.l" +YY_RULE_SETUP case YY_STATE_EOF(xeu): #line 685 "scan.l" { @@ -5658,12 +5885,15 @@ YY_RULE_SETUP * spacing between ? as a substition character and a simple operator (e.g. "?=?") */ if (yytext[0] == '?' && + strcmp(yytext, "?<@") != 0 && strcmp(yytext, "?@>") != 0 && + strcmp(yytext, "?~") != 0 && strcmp(yytext, "?@") != 0 && strcmp(yytext, "?|") != 0 && strcmp(yytext, "?&") != 0 && strcmp(yytext, "?#") != 0 && strcmp(yytext, "?-") != 0 && strcmp(yytext, "?-|") != 0 && strcmp(yytext, "?||") != 0) nchars = 1; if (yytext[0] != '?' && strchr(yytext, '?') && + strcmp(yytext, "^?") != 0 && strcmp(yytext, "#?") != 0 && strcmp(yytext, "@?") != 0) /* Lex up to just before the ? character */ nchars = strchr(yytext, '?') - yytext; @@ -5719,7 +5949,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 1016 "scan.l" +#line 1019 "scan.l" { SET_YYLLOC(); yylval->ival = atol(yytext + 1); @@ -5728,7 +5958,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 1022 "scan.l" +#line 1025 "scan.l" { SET_YYLLOC(); return process_integer_literal(yytext, yylval); @@ -5736,7 +5966,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 1026 "scan.l" +#line 1029 "scan.l" { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -5745,7 +5975,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 1031 "scan.l" +#line 1034 "scan.l" { /* throw back the .., and treat as integer */ yyless(yyleng - 2); @@ -5755,7 +5985,7 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 1037 "scan.l" +#line 1040 "scan.l" { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -5764,7 +5994,7 @@ YY_RULE_SETUP YY_BREAK case 62: YY_RULE_SETUP -#line 1042 "scan.l" +#line 1045 "scan.l" { /* * throw back the [Ee], and figure out whether what @@ -5777,7 +6007,7 @@ YY_RULE_SETUP YY_BREAK case 63: YY_RULE_SETUP -#line 1051 "scan.l" +#line 1054 "scan.l" { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); @@ -5787,7 +6017,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 1059 "scan.l" +#line 1062 "scan.l" { int kwnum; char *ident; @@ -5821,14 +6051,14 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 1090 "scan.l" +#line 1093 "scan.l" { SET_YYLLOC(); return yytext[0]; } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 1095 "scan.l" +#line 1098 "scan.l" { SET_YYLLOC(); yyterminate(); @@ -5836,10 +6066,10 @@ case YY_STATE_EOF(INITIAL): YY_BREAK case 66: YY_RULE_SETUP -#line 1100 "scan.l" +#line 1103 "scan.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 5794 "scan.c" +#line 6023 "scan.c" case YY_END_OF_BUFFER: { @@ -5855,7 +6085,7 @@ YY_FATAL_ERROR( "flex scanner jammed" ); /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called - * core_yylex(). If so, then we have to assure + * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a @@ -5915,7 +6145,7 @@ YY_FATAL_ERROR( "flex scanner jammed" ); { yyg->yy_did_buffer_switch_on_eof = 0; - if ( core_yywrap(yyscanner ) ) + if ( yywrap( yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up @@ -5968,7 +6198,8 @@ YY_FATAL_ERROR( "flex scanner jammed" ); "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ -} /* end of core_yylex */ + } /* end of user's declarations */ +} /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * @@ -5980,9 +6211,9 @@ YY_FATAL_ERROR( "flex scanner jammed" ); static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = yyg->yytext_ptr; + int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) @@ -6011,7 +6242,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -6031,7 +6262,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); @@ -6047,11 +6278,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner) b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ - core_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); } else /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( @@ -6079,7 +6311,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; - core_yyrestart(yyin ,yyscanner); + yyrestart( yyin , yyscanner); } else @@ -6093,12 +6325,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else ret_val = EOB_ACT_CONTINUE_SCAN; - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) core_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } yyg->yy_n_chars += number_to_move; @@ -6114,8 +6349,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yy_start_state_list[yyg->yy_start]; @@ -6135,20 +6370,24 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { - register int yy_is_jam; + int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register int yy_c = 256; - register yyconst struct yy_trans_info *yy_trans_info; + int yy_c = 256; + const struct yy_trans_info *yy_trans_info; yy_trans_info = &yy_current_state[(unsigned int) yy_c]; yy_current_state += yy_trans_info->yy_nxt; yy_is_jam = (yy_trans_info->yy_verify != yy_c); - (void) yyg; + (void)yyg; return yy_is_jam ? 0 : yy_current_state; } +#ifndef YY_NO_UNPUT + +#endif + #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) @@ -6191,13 +6430,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ /* Reset buffer status. */ - core_yyrestart(yyin ,yyscanner); + yyrestart( yyin , yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { - if ( core_yywrap(yyscanner ) ) + if ( yywrap( yyscanner ) ) return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) @@ -6229,34 +6468,34 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ - void core_yyrestart (FILE * input_file , yyscan_t yyscanner) + void yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ - core_yyensure_buffer_stack (yyscanner); + yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = - core_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); } - core_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - core_yy_load_buffer_state(yyscanner ); + yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); + yy_load_buffer_state( yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ - void core_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with - * core_yypop_buffer_state(); - * core_yypush_buffer_state(new_buffer); + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); */ - core_yyensure_buffer_stack (yyscanner); + yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; @@ -6269,17 +6508,17 @@ static int yy_get_next_buffer (yyscan_t yyscanner) } YY_CURRENT_BUFFER_LVALUE = new_buffer; - core_yy_load_buffer_state(yyscanner ); + yy_load_buffer_state( yyscanner ); /* We don't actually know whether we did this switch during - * EOF (core_yywrap()) processing, but the only time this flag - * is looked at is after core_yywrap() is called, so it's safe + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } -static void core_yy_load_buffer_state (yyscan_t yyscanner) +static void yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; @@ -6294,32 +6533,32 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) * @param yyscanner The scanner object. * @return the allocated buffer state. */ - YY_BUFFER_STATE core_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) core_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in core_yy_create_buffer()" ); + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) core_yyalloc(b->yy_buf_size + 2 ,yyscanner ); + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in core_yy_create_buffer()" ); + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; - core_yy_init_buffer(b,file ,yyscanner); + yy_init_buffer( b, file , yyscanner); return b; } /** Destroy the buffer. - * @param b a buffer created with core_yy_create_buffer() + * @param b a buffer created with yy_create_buffer() * @param yyscanner The scanner object. */ @@ -6327,21 +6566,21 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, - * such as during a core_yyrestart() or at EOF. + * such as during a yyrestart() or at EOF. */ - static void core_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - core_yy_flush_buffer(b ,yyscanner); + yy_flush_buffer( b , yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; - /* If b is the current buffer, then core_yy_init_buffer was _probably_ - * called from core_yyrestart() or through yy_get_next_buffer. + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ @@ -6358,7 +6597,7 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ - void core_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) + void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) @@ -6379,7 +6618,7 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) - core_yy_load_buffer_state(yyscanner ); + yy_load_buffer_state( yyscanner ); } /** Pushes the new state onto the stack. The new state becomes @@ -6399,7 +6638,7 @@ static void core_yy_load_buffer_state (yyscan_t yyscanner) /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ -static void core_yyensure_buffer_stack (yyscan_t yyscanner) +static void yyensure_buffer_stack (yyscan_t yyscanner) { yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; @@ -6410,15 +6649,15 @@ static void core_yyensure_buffer_stack (yyscan_t yyscanner) * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)core_yyalloc + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in core_yyensure_buffer_stack()" ); - + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; @@ -6427,15 +6666,15 @@ static void core_yyensure_buffer_stack (yyscan_t yyscanner) if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; + yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)core_yyrealloc + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in core_yyensure_buffer_stack()" ); + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); @@ -6447,9 +6686,9 @@ static void core_yyensure_buffer_stack (yyscan_t yyscanner) * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE core_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; @@ -6457,41 +6696,41 @@ YY_BUFFER_STATE core_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yy base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ - return 0; + return NULL; - b = (YY_BUFFER_STATE) core_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in core_yy_scan_buffer()" ); + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; - b->yy_input_file = 0; + b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; - core_yy_switch_to_buffer(b ,yyscanner ); + yy_switch_to_buffer( b , yyscanner ); return b; } -/** Setup the input buffer state to scan a string. The next call to core_yylex() will +/** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use - * core_yy_scan_bytes() instead. + * yy_scan_bytes() instead. */ -/** Setup the input buffer state to scan the given bytes. The next call to core_yylex() will +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ @@ -6501,9 +6740,11 @@ YY_BUFFER_STATE core_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yy #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) { - (void) fprintf( stderr, "%s\n", msg ); + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } @@ -6514,7 +6755,7 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) do \ { \ /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ + yy_size_t yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ @@ -6566,29 +6807,29 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ -void core_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. - * @param line_number + * @param _line_number line number * @param yyscanner The scanner object. */ /** Set the current column. - * @param line_number + * @param _column_no column number * @param yyscanner The scanner object. */ /** Set the input stream. This does not discard the current * input buffer. - * @param in_str A readable stream. + * @param _in_str A readable stream. * @param yyscanner The scanner object. - * @see core_yy_switch_to_buffer + * @see yy_switch_to_buffer */ @@ -6610,20 +6851,18 @@ void core_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) /* User-visible API */ -/* core_yylex_init is special because it creates the scanner itself, so it is +/* yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ - -int core_yylex_init(yyscan_t* ptr_yy_globals) - +int yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } - *ptr_yy_globals = (yyscan_t) core_yyalloc ( sizeof( struct yyguts_t ), NULL ); + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; @@ -6636,27 +6875,26 @@ int core_yylex_init(yyscan_t* ptr_yy_globals) return yy_init_globals ( *ptr_yy_globals ); } -/* core_yylex_init_extra has the same functionality as core_yylex_init, but follows the +/* yylex_init_extra has the same functionality as yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to core_yyalloc in + * The user defined value in the first argument will be available to yyalloc in * the yyextra field. */ - static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. - * This function is called from core_yylex_destroy(), so don't allocate here. + * This function is called from yylex_destroy(), so don't allocate here. */ - yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; + yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; @@ -6669,17 +6907,17 @@ static int yy_init_globals (yyscan_t yyscanner) yyin = stdin; yyout = stdout; #else - yyin = (FILE *) 0; - yyout = (FILE *) 0; + yyin = NULL; + yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by - * core_yylex_init() + * yylex_init() */ return 0; } -/* core_yylex_destroy is for both reentrant and non-reentrant scanners. */ +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ /* @@ -6687,18 +6925,21 @@ static int yy_init_globals (yyscan_t yyscanner) */ #ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) { - register int i; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +static int yy_flex_strlen (const char * s , yyscan_t yyscanner) { - register int n; + int n; for ( n = 0; s[n]; ++n ) ; @@ -6708,14 +6949,13 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1100 "scan.l" - +#line 1103 "scan.l" /* LCOV_EXCL_STOP */ /* - * Arrange access to yyextra for subroutines of the main core_yylex() function. + * Arrange access to yyextra for subroutines of the main yylex() function. * We expect each subroutine to have a yyscanner parameter. Rather than * use the yyget_xxx functions, which might or might not get inlined by the * compiler, we cheat just a bit and cast yyscanner to the right type. @@ -6817,7 +7057,7 @@ cancel_scanner_errposition_callback(ScannerCallbackState *scbstate) * Report a lexer or grammar error. * * The message's cursor position is whatever YYLLOC was last set to, - * ie, the start of the current token if called within core_yylex(), or the + * ie, the start of the current token if called within yylex(), or the * most recently lexed token if called from the grammar. * This is OK for syntax error messages from the Bison parser, because Bison * parsers report error as soon as the first unparsable token is reached. @@ -6860,8 +7100,8 @@ scanner_init(const char *str, Size slen = strlen(str); yyscan_t scanner; - if (core_yylex_init(&scanner) != 0) - elog(ERROR, "core_yylex_init() failed: %m"); + if (yylex_init(&scanner) != 0) + elog(ERROR, "yylex_init() failed: %m"); core_yyset_extra(yyext, scanner); @@ -6879,7 +7119,7 @@ scanner_init(const char *str, yyext->scanbuflen = slen; memcpy(yyext->scanbuf, str, slen); yyext->scanbuf[slen] = yyext->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; - core_yy_scan_buffer(yyext->scanbuf,slen + 2,scanner); + yy_scan_buffer(yyext->scanbuf, slen + 2, scanner); /* initialize literal buffer to a reasonable but expansible size */ yyext->literalalloc = 1024; @@ -6897,7 +7137,7 @@ void scanner_finish(core_yyscan_t yyscanner) { /* - * We don't bother to call core_yylex_destroy(), because all it would do is + * We don't bother to call yylex_destroy(), because all it would do is * pfree a small amount of control storage. It's cheaper to leak the * storage until the parsing context is destroyed. The amount of space * involved is usually negligible compared to the output parse tree diff --git a/ext/pg_query/src_backend_tcop_postgres.c b/ext/pg_query/src_backend_tcop_postgres.c index d7c84962..02d4d313 100644 --- a/ext/pg_query/src_backend_tcop_postgres.c +++ b/ext/pg_query/src_backend_tcop_postgres.c @@ -55,7 +55,6 @@ #include "catalog/pg_type.h" #include "commands/async.h" #include "commands/prepare.h" -#include "executor/spi.h" #include "jit/jit.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" @@ -520,6 +519,12 @@ static void disable_statement_timeout(void); * If an interrupt condition is pending, and it's safe to service it, * then clear the flag and accept the interrupt. Called only when * InterruptPending is true. + * + * Note: if INTERRUPTS_CAN_BE_PROCESSED() is true, then ProcessInterrupts + * is guaranteed to clear the InterruptPending flag before returning. + * (This is not the same as guaranteeing that it's still clear when we + * return; another interrupt could have arrived. But we promise that + * any pre-existing one will have been serviced.) */ void ProcessInterrupts(void) {} @@ -568,9 +573,14 @@ ia64_get_bsp(void) * * Returns the old reference point, if any. */ +#ifndef HAVE__BUILTIN_FRAME_ADDRESS +#endif #if defined(__ia64__) || defined(__ia64) #else #endif +#ifdef HAVE__BUILTIN_FRAME_ADDRESS +#else +#endif #if defined(__ia64__) || defined(__ia64) #endif diff --git a/ext/pg_query/src_backend_utils_adt_ruleutils.c b/ext/pg_query/src_backend_utils_adt_ruleutils.c index 567afdb7..00ea82ef 100644 --- a/ext/pg_query/src_backend_utils_adt_ruleutils.c +++ b/ext/pg_query/src_backend_utils_adt_ruleutils.c @@ -62,6 +62,7 @@ #include "parser/parse_func.h" #include "parser/parse_node.h" #include "parser/parse_oper.h" +#include "parser/parse_relation.h" #include "parser/parser.h" #include "parser/parsetree.h" #include "rewrite/rewriteHandler.h" @@ -392,26 +393,29 @@ static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags, int wrapColumn); static void get_query_def(Query *query, StringInfo buf, List *parentnamespace, - TupleDesc resultDesc, + TupleDesc resultDesc, bool colNamesVisible, int prettyFlags, int wrapColumn, int startIndent); static void get_values_def(List *values_lists, deparse_context *context); static void get_with_clause(Query *query, deparse_context *context); static void get_select_query_def(Query *query, deparse_context *context, - TupleDesc resultDesc); -static void get_insert_query_def(Query *query, deparse_context *context); -static void get_update_query_def(Query *query, deparse_context *context); + TupleDesc resultDesc, bool colNamesVisible); +static void get_insert_query_def(Query *query, deparse_context *context, + bool colNamesVisible); +static void get_update_query_def(Query *query, deparse_context *context, + bool colNamesVisible); static void get_update_query_targetlist_def(Query *query, List *targetList, deparse_context *context, RangeTblEntry *rte); -static void get_delete_query_def(Query *query, deparse_context *context); +static void get_delete_query_def(Query *query, deparse_context *context, + bool colNamesVisible); static void get_utility_query_def(Query *query, deparse_context *context); static void get_basic_select_query(Query *query, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc, bool colNamesVisible); static void get_target_list(List *targetList, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc, bool colNamesVisible); static void get_setop_query(Node *setOp, Query *query, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc, bool colNamesVisible); static Node *get_rule_sortgroupclause(Index ref, List *tlist, bool force_colno, deparse_context *context); @@ -440,6 +444,8 @@ static void get_rule_expr(Node *node, deparse_context *context, bool showimplicit); static void get_rule_expr_toplevel(Node *node, deparse_context *context, bool showimplicit); +static void get_rule_list_toplevel(List *lst, deparse_context *context, + bool showimplicit); static void get_rule_expr_funccall(Node *node, deparse_context *context, bool showimplicit); static bool looks_like_function(Node *node); @@ -1037,8 +1043,18 @@ static void get_reloptions(StringInfo buf, Datum reloptions); /* ---------- * get_query_def - Parse back one query parsetree * - * If resultDesc is not NULL, then it is the output tuple descriptor for - * the view represented by a SELECT query. + * query: parsetree to be displayed + * buf: output text is appended to buf + * parentnamespace: list (initially empty) of outer-level deparse_namespace's + * resultDesc: if not NULL, the output tuple descriptor for the view + * represented by a SELECT query. We use the column names from it + * to label SELECT output columns, in preference to names in the query + * colNamesVisible: true if the surrounding context cares about the output + * column names at all (as, for example, an EXISTS() context does not); + * when false, we can suppress dummy column labels such as "?column?" + * prettyFlags: bitmask of PRETTYFLAG_XXX options + * wrapColumn: maximum line length, or -1 to disable wrapping + * startIndent: initial indentation amount * ---------- */ @@ -1074,6 +1090,8 @@ static void get_reloptions(StringInfo buf, Datum reloptions); * get_target_list - Parse back a SELECT target list * * This is also used for RETURNING lists in INSERT/UPDATE/DELETE. + * + * resultDesc and colNamesVisible are as for get_query_def() * ---------- */ @@ -1291,6 +1309,16 @@ static void get_reloptions(StringInfo buf, Datum reloptions); */ +/* + * get_rule_list_toplevel - Parse back a list of toplevel expressions + * + * Apply get_rule_expr_toplevel() to each element of a List. + * + * This adds commas between the expressions, but caller is responsible + * for printing surrounding decoration. + */ + + /* * get_rule_expr_funccall - Parse back a function-call expression * diff --git a/ext/pg_query/src_backend_utils_misc_guc.c b/ext/pg_query/src_backend_utils_misc_guc.c index 5be929b9..0155ef79 100644 --- a/ext/pg_query/src_backend_utils_misc_guc.c +++ b/ext/pg_query/src_backend_utils_misc_guc.c @@ -49,6 +49,7 @@ #include "catalog/storage.h" #include "commands/async.h" #include "commands/prepare.h" +#include "commands/tablespace.h" #include "commands/trigger.h" #include "commands/user.h" #include "commands/vacuum.h" diff --git a/ext/pg_query/src_common_wchar.c b/ext/pg_query/src_common_wchar.c index 8a1228e5..339ede6d 100644 --- a/ext/pg_query/src_common_wchar.c +++ b/ext/pg_query/src_common_wchar.c @@ -1618,6 +1618,11 @@ const pg_wchar_tbl pg_wchar_table[] = { /* * Returns the byte length of a multibyte character. + * + * Caution: when dealing with text that is not certainly valid in the + * specified encoding, the result may exceed the actual remaining + * string length. Callers that are not prepared to deal with that + * should use pg_encoding_mblen_bounded() instead. */ int pg_encoding_mblen(int encoding, const char *mbstr) @@ -1627,6 +1632,12 @@ pg_encoding_mblen(int encoding, const char *mbstr) pg_wchar_table[PG_SQL_ASCII].mblen((const unsigned char *) mbstr)); } +/* + * Returns the byte length of a multibyte character; but not more than + * the distance to end of string. + */ + + /* * Returns the display length of a multibyte character. */ diff --git a/ext/pg_query/src_pl_plpgsql_src_pl_comp.c b/ext/pg_query/src_pl_plpgsql_src_pl_comp.c index 3f54b842..95d60a68 100644 --- a/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +++ b/ext/pg_query/src_pl_plpgsql_src_pl_comp.c @@ -385,9 +385,11 @@ add_dummy_return(PLpgSQL_function *function) /* * If the outer block has an EXCEPTION clause, we need to make a new outer * block, since the added RETURN shouldn't act like it is inside the - * EXCEPTION clause. + * EXCEPTION clause. Likewise, if it has a label, wrap it in a new outer + * block so that EXIT doesn't skip the RETURN. */ - if (function->action->exceptions != NULL) + if (function->action->exceptions != NULL || + function->action->label != NULL) { PLpgSQL_stmt_block *new; diff --git a/ext/pg_query/src_pl_plpgsql_src_pl_gram.c b/ext/pg_query/src_pl_plpgsql_src_pl_gram.c index a3ac4064..ab91977e 100644 --- a/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +++ b/ext/pg_query/src_pl_plpgsql_src_pl_gram.c @@ -5535,7 +5535,7 @@ make_execsql_stmt(int firsttoken, int location) check_sql_expr(expr->query, location, 0); - execsql = palloc(sizeof(PLpgSQL_stmt_execsql)); + execsql = palloc0(sizeof(PLpgSQL_stmt_execsql)); execsql->cmd_type = PLPGSQL_STMT_EXECSQL; execsql->lineno = plpgsql_location_to_lineno(location); execsql->stmtid = ++plpgsql_curr_compile->nstatements; diff --git a/ext/pg_query/src_port_pg_bitutils.c b/ext/pg_query/src_port_pg_bitutils.c index 847c02a3..39a16f19 100644 --- a/ext/pg_query/src_port_pg_bitutils.c +++ b/ext/pg_query/src_port_pg_bitutils.c @@ -1,13 +1,6 @@ /*-------------------------------------------------------------------- * Symbols referenced in this file: * - pg_popcount64 - * - pg_popcount64_choose - * - pg_popcount32 - * - pg_popcount32_choose - * - pg_popcount_available - * - pg_popcount32_asm - * - pg_popcount64_asm - * - pg_popcount32_slow * - pg_popcount64_slow *-------------------------------------------------------------------- */ @@ -92,7 +85,7 @@ static int pg_popcount64_asm(uint64 word); int (*pg_popcount32) (uint32 word) = pg_popcount32_choose; int (*pg_popcount64) (uint64 word) = pg_popcount64_choose; #else -int (*pg_popcount32) (uint32 word) = pg_popcount32_slow; + int (*pg_popcount64) (uint64 word) = pg_popcount64_slow; #endif /* USE_POPCNT_ASM */ @@ -190,23 +183,9 @@ __asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc"); * pg_popcount32_slow * Return the number of 1 bits set in word */ -static int -pg_popcount32_slow(uint32 word) -{ #ifdef HAVE__BUILTIN_POPCOUNT - return __builtin_popcount(word); #else /* !HAVE__BUILTIN_POPCOUNT */ - int result = 0; - - while (word != 0) - { - result += pg_number_of_ones[word & 255]; - word >>= 8; - } - - return result; #endif /* HAVE__BUILTIN_POPCOUNT */ -} /* * pg_popcount64_slow diff --git a/ext/pg_query/src_port_snprintf.c b/ext/pg_query/src_port_snprintf.c index 1b3f1710..578e5fd9 100644 --- a/ext/pg_query/src_port_snprintf.c +++ b/ext/pg_query/src_port_snprintf.c @@ -344,7 +344,7 @@ static bool find_arguments(const char *format, va_list args, PrintfArgValue *argvalues); static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth, int pointflag, PrintfTarget *target); -static void fmtptr(void *value, PrintfTarget *target); +static void fmtptr(const void *value, PrintfTarget *target); static void fmtint(long long value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target); @@ -418,7 +418,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) int cvalue; long long numvalue; double fvalue; - char *strvalue; + const char *strvalue; PrintfArgValue argvalues[PG_NL_ARGMAX + 1]; /* @@ -463,7 +463,8 @@ dopr(PrintfTarget *target, const char *format, va_list args) { format++; strvalue = va_arg(args, char *); - Assert(strvalue != NULL); + if (strvalue == NULL) + strvalue = "(null)"; dostr(strvalue, strlen(strvalue), target); if (target->failed) break; @@ -694,8 +695,9 @@ dopr(PrintfTarget *target, const char *format, va_list args) strvalue = argvalues[fmtpos].cptr; else strvalue = va_arg(args, char *); - /* Whine if someone tries to print a NULL string */ - Assert(strvalue != NULL); + /* If string is NULL, silently substitute "(null)" */ + if (strvalue == NULL) + strvalue = "(null)"; fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag, target); break; @@ -705,7 +707,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) strvalue = argvalues[fmtpos].cptr; else strvalue = va_arg(args, char *); - fmtptr((void *) strvalue, target); + fmtptr((const void *) strvalue, target); break; case 'e': case 'E': @@ -1019,7 +1021,7 @@ fmtstr(const char *value, int leftjust, int minlen, int maxwidth, } static void -fmtptr(void *value, PrintfTarget *target) +fmtptr(const void *value, PrintfTarget *target) { int vallen; char convert[64]; diff --git a/lib/pg_query/fingerprint.rb b/lib/pg_query/fingerprint.rb index 0078a469..d1c15bf7 100644 --- a/lib/pg_query/fingerprint.rb +++ b/lib/pg_query/fingerprint.rb @@ -39,6 +39,11 @@ def fingerprint_value(val, hash, parent_node_name, parent_field_name, need_to_wr subhash = FingerprintSubHash.new if val.is_a?(Google::Protobuf::RepeatedField) + # For lists that have exactly one untyped node, just output the parent field (if needed) and return + if val.length == 1 && val[0].is_a?(Node) && val[0].node.nil? + hash.update(parent_field_name) if need_to_write_name + return + end fingerprint_list(val, subhash, parent_node_name, parent_field_name) elsif val.is_a?(List) fingerprint_list(val.items, subhash, parent_node_name, parent_field_name) @@ -90,12 +95,18 @@ def fingerprint_node(node, hash, parent_node_name = nil, parent_field_name = nil when 'location' next when 'name' - next if [PrepareStmt, ExecuteStmt, DeallocateStmt].include?(node.class) + next if [PrepareStmt, ExecuteStmt, DeallocateStmt, FunctionParameter].include?(node.class) next if node.is_a?(ResTarget) && parent_node_name == 'SelectStmt' && parent_field_name == 'targetList' - when 'gid', 'options', 'savepoint_name' + when 'gid', 'savepoint_name' next if node.is_a?(TransactionStmt) + when 'options' + next if [TransactionStmt, CreateFunctionStmt].include?(node.class) when 'portalname' next if [DeclareCursorStmt, FetchStmt, ClosePortalStmt].include?(node.class) + when 'conditionname' + next if [ListenStmt, UnlistenStmt, NotifyStmt].include?(node.class) + when 'args' + next if node.is_a?(DoStmt) when 'relname' next if node.is_a?(RangeVar) && node.relpersistence == 't' if node.is_a?(RangeVar) diff --git a/lib/pg_query/pg_query_pb.rb b/lib/pg_query/pg_query_pb.rb index 215b9cc2..c0513a76 100644 --- a/lib/pg_query/pg_query_pb.rb +++ b/lib/pg_query/pg_query_pb.rb @@ -809,6 +809,7 @@ optional :def, :message, 5, "pg_query.Node", json_name: "def" optional :behavior, :enum, 6, "pg_query.DropBehavior", json_name: "behavior" optional :missing_ok, :bool, 7, json_name: "missing_ok" + optional :recurse, :bool, 8, json_name: "recurse" end add_message "pg_query.AlterDomainStmt" do optional :subtype, :string, 1, json_name: "subtype" @@ -2766,7 +2767,7 @@ value :REASSIGN, 579 value :RECHECK, 580 value :RECURSIVE, 581 - value :REF, 582 + value :REF_P, 582 value :REFERENCES, 583 value :REFERENCING, 584 value :REFRESH, 585 diff --git a/spec/files/fingerprint.json b/spec/files/fingerprint.json index 4724fe93..dbbc7501 100644 --- a/spec/files/fingerprint.json +++ b/spec/files/fingerprint.json @@ -425,5 +425,55 @@ "input": "SELECT * FROM t_2", "expectedParts": ["RawStmt", "stmt", "SelectStmt", "fromClause", "RangeVar", "inh", "true", "relname", "t_2", "relpersistence", "p", "limitOption", "LIMIT_OPTION_DEFAULT", "op", "SETOP_NONE", "targetList", "ResTarget", "val", "ColumnRef", "fields", "A_Star"], "expectedHash": "3f1444da570c1a66" + }, + { + "input": "CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response \"mytable\", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_12345$ BEGIN INSERT INTO \"mytable\" (\"mycolumn\") VALUES ('myvalue') RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_12345$ LANGUAGE plpgsql; SELECT (testfunc.response).\"mycolumn\", testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();", + "expectedParts": ["RawStmt", "stmt", "CreateFunctionStmt", "funcname", "String", "str", "pg_temp", "String", "str", "testfunc", "parameters", "FunctionParameter", "argType", "names", "String", "str", "mytable", "typemod", "-1", "mode", "FUNC_PARAM_OUT", "FunctionParameter", "argType", "names", "String", "str", "text", "typemod", "-1", "mode", "FUNC_PARAM_OUT", "replace", "true", "returnType", "names", "String", "str", "record", "typemod", "-1", "RawStmt", "stmt", "SelectStmt", "fromClause", "RangeFunction", "functions", "FuncCall", "funcname", "String", "str", "pg_temp", "String", "str", "testfunc", "limitOption", "LIMIT_OPTION_DEFAULT", "op", "SETOP_NONE", "targetList", "ResTarget", "val", "A_Indirection", "arg", "ColumnRef", "fields", "String", "str", "testfunc", "String", "str", "response", "indirection", "String", "str", "mycolumn", "ResTarget", "val", "ColumnRef", "fields", "String", "str", "testfunc", "String", "str", "sequelize_caught_exception", "RawStmt", "stmt", "DropStmt", "behavior", "DROP_RESTRICT", "missing_ok", "true", "objects", "ObjectWithArgs", "objname", "String", "str", "pg_temp", "String", "str", "testfunc", "removeType", "OBJECT_FUNCTION"], + "expectedHash": "8644cf89251e2157" + }, + { + "input": "CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL AS $$ INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); $$;", + "expectedParts": ["RawStmt", "stmt", "CreateFunctionStmt", "funcname", "String", "str", "insert_data", "is_procedure", "true", "parameters", "FunctionParameter", "argType", "names", "String", "str", "pg_catalog", "String", "str", "int4", "typemod", "-1", "mode", "FUNC_PARAM_IN", "FunctionParameter", "argType", "names", "String", "str", "pg_catalog", "String", "str", "int4", "typemod", "-1", "mode", "FUNC_PARAM_IN"], + "expectedHash": "3d7c3d242d7990a5" + }, + { + "input": "DO $$DECLARE r record; BEGIN FOR r IN SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'VIEW' AND table_schema = 'public' LOOP EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser'; END LOOP; END$$;", + "expectedParts": ["RawStmt", "stmt", "DoStmt"], + "expectedHash": "f936eab75b8c1b90" + }, + { + "input": "LISTEN virtual", + "expectedParts": ["RawStmt", "stmt", "ListenStmt"], + "expectedHash": "6e5bf26e5fc272a5" + }, + { + "input": "UNLISTEN virtual", + "expectedParts": ["RawStmt", "stmt", "UnlistenStmt"], + "expectedHash": "9348a760200458ff" + }, + { + "input": "UNLISTEN *", + "expectedParts": ["RawStmt", "stmt", "UnlistenStmt"], + "expectedHash": "9348a760200458ff" + }, + { + "input": "NOTIFY virtual", + "expectedParts": ["RawStmt", "stmt", "NotifyStmt"], + "expectedHash": "92f42ef7b6fa8f62" + }, + { + "input": "SELECT DISTINCT id FROM mytable", + "expectedParts": ["RawStmt", "stmt", "SelectStmt", "distinctClause", "fromClause", "RangeVar", "inh", "true", "relname", "mytable", "relpersistence", "p", "limitOption", "LIMIT_OPTION_DEFAULT", "op", "SETOP_NONE", "targetList", "ResTarget", "val", "ColumnRef", "fields", "String", "str", "id"], + "expectedHash": "3a7e897d3710fa93" + }, + { + "input": "SELECT DISTINCT ON (id) id FROM mytable", + "expectedParts": ["RawStmt", "stmt", "SelectStmt", "distinctClause", "ColumnRef", "fields", "String", "str", "id", "fromClause", "RangeVar", "inh", "true", "relname", "mytable", "relpersistence", "p", "limitOption", "LIMIT_OPTION_DEFAULT", "op", "SETOP_NONE", "targetList", "ResTarget", "val", "ColumnRef", "fields", "String", "str", "id"], + "expectedHash": "44bc30469a1802ea" + }, + { + "input": "SELECT id FROM mytable", + "expectedParts": ["RawStmt", "stmt", "SelectStmt", "fromClause", "RangeVar", "inh", "true", "relname", "mytable", "relpersistence", "p", "limitOption", "LIMIT_OPTION_DEFAULT", "op", "SETOP_NONE", "targetList", "ResTarget", "val", "ColumnRef", "fields", "String", "str", "id"], + "expectedHash": "40991573eb85c5f6" } ] diff --git a/spec/lib/normalized_parsing_spec.rb b/spec/lib/normalized_parsing_spec.rb index 0237894a..474e31a2 100644 --- a/spec/lib/normalized_parsing_spec.rb +++ b/spec/lib/normalized_parsing_spec.rb @@ -277,7 +277,7 @@ def parse_expr(expr) # support that due to keyword/function duality (e.g. JOIN) expect { described_class.parse("SELECT ? 10") }.to raise_error do |error| expect(error).to be_a(described_class::ParseError) - expect(error.message).to eq "syntax error at or near \"10\" (scan.l:1230)" + expect(error.message).to eq "syntax error at or near \"10\" (scan.l:1232)" end end diff --git a/spec/lib/parse_spec.rb b/spec/lib/parse_spec.rb index d880ac33..a2c5338b 100644 --- a/spec/lib/parse_spec.rb +++ b/spec/lib/parse_spec.rb @@ -66,7 +66,7 @@ it "handles errors" do expect { described_class.parse("SELECT 'ERR") }.to(raise_error do |error| expect(error).to be_a(PgQuery::ParseError) - expect(error.message).to eq "unterminated quoted string at or near \"'ERR\" (scan.l:1230)" + expect(error.message).to eq "unterminated quoted string at or near \"'ERR\" (scan.l:1232)" expect(error.location).to eq 8 # 8th character in query string end) end @@ -450,7 +450,7 @@ it 'fails to parse CREATE TABLE WITH OIDS' do expect { described_class.parse("CREATE TABLE test (a int4) WITH OIDS") }.to(raise_error do |error| expect(error).to be_a(PgQuery::ParseError) - expect(error.message).to eq "syntax error at or near \"OIDS\" (scan.l:1230)" + expect(error.message).to eq "syntax error at or near \"OIDS\" (scan.l:1232)" expect(error.location).to eq 33 # 33rd character in query string end) end diff --git a/spec/lib/pg_query/deparse_bad_tree_spec.rb b/spec/lib/pg_query/deparse_bad_tree_spec.rb index e3b2113e..0a3c83b2 100644 --- a/spec/lib/pg_query/deparse_bad_tree_spec.rb +++ b/spec/lib/pg_query/deparse_bad_tree_spec.rb @@ -25,7 +25,7 @@ expect { PgQuery.deparse(tree) }.to raise_error do |error| expect(error).to be_a(described_class::ParseError) - expect(error.message).to eq "deparse error in deparseTargetList: ResTarget without val (pg_query_deparse.c:1419)" + expect(error.message).to eq "deparse: error in deparseTargetList: ResTarget without val (pg_query_deparse.c:1417)" end end end