Use fast-hash for Query ID jumbling#79
Open
lfittl wants to merge 36 commits into
Open
Conversation
9903eeb to
78ab5f6
Compare
This needs to be wary of the function volatility changing after we check it. We cannot enforce this when checking at parse time, so move it later, into the planner. Author: Paul A. Jungwirth <pj@illuminatedcomputing.com> Reported-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: jian he <jian.universality@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUte0_UJsJiDJQi82oaBsMJn%3Dcct0Wn%3DvOqXtuDn%3DYYJA%40mail.gmail.com
We should defer validating FDW usage until after analysis. We have to guard against not just the topmost table, but also individual child partitions. Added the check to CheckValidResultRel, because it is called after looking up child partitions (accounting for pruning), but before the FDW can run a DirectModify update, which would bypass per-tuple executor work. Author: jian he <jian.universality@gmail.com> Reported-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Paul A. Jungwirth <pj@illuminatedcomputing.com> Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUte0_UJsJiDJQi82oaBsMJn%3Dcct0Wn%3DvOqXtuDn%3DYYJA%40mail.gmail.com
When COPY TO with FORMAT json is given an explicit column list that names all columns in a different order, the JSON output incorrectly used the table's physical column order instead of the requested order. This happened because BeginCopyTo() only built a restricted TupleDesc when list_length(attnumlist) < tupDesc->natts. When all columns are listed (just reordered), this condition was false and no projected TupleDesc was built, causing CopyToJsonOneRow() to emit columns in physical order. Fix by also building the projected TupleDesc when an explicit column list was provided (attnamelist != NIL), even if it names all columns. Author: Baji Shaik <baji.pgdev@gmail.com> Reviewed-by: Andrew Dunstan <andrew@dunslane.net> Discussion: https://postgr.es/m/CA+fm-ROd4cNKM524n6EdgtZ9xOzOHJDNv8J_9Mvr2+2t1qWSDw@mail.gmail.com
Disallow marking an inherited CHECK constraint as NOT ENFORCED when an equivalent parent constraint remains ENFORCED. This prevents ALTER CONSTRAINT from producing a child constraint that is weaker than one of its inherited parent definitions. When recursively altering a CHECK constraint to NOT ENFORCED, collect the corresponding constraints in the affected inheritance subtree and ignore those parent constraints while checking descendants. If a descendant also inherits an equivalent ENFORCED constraint from a parent outside the current ALTER, keep the descendant ENFORCED by merging to the stricter state. This was missed in commit 342051d, which introduced the ability to alter CHECK constraint enforceability. Add regression coverage for direct child ALTER, ONLY ALTER, mixed-parent inheritance, and a common-ancestor diamond where all equivalent inherited constraints can be changed together. Author: Chao Li <lic@highgo.com> Reviewed-by: Jian He <jian.universality@gmail.com> Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com
Update the table inheritance documentation to mention not-null constraints alongside check constraints where inherited constraints are discussed. Also clarify that some properties of inherited constraints can now be altered directly on child tables, while the resulting constraint must remain compatible with its inherited parent constraints. For multiple inheritance, say explicitly that when a column or constraint is inherited from more than one parent, the stricter definition applies. Author: Chao Li <lic@highgo.com> Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com> Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com
The ALTER TABLE documentation said that FOREIGN KEY and CHECK constraints may be altered, but did not distinguish between deferrability and enforceability attributes. Clarify that deferrability attributes can currently be altered only for FOREIGN KEY constraints, while enforceability can be altered for both FOREIGN KEY and CHECK constraints. Also document that setting a constraint to ENFORCED verifies existing rows and resumes checking new or updated rows. Author: Chao Li <lic@highgo.com> Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com> Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com Discussion: https://postgr.es/m/711B1ED3-1781-4B6C-A573-B58AF20770E5@gmail.com
Replace the VARIADIC text[] alternating key/value option interface with typed named boolean parameters for pg_get_role_ddl(), pg_get_tablespace_ddl(), and pg_get_database_ddl(), as added by commit 4881981 and friends. The new signatures are: pg_get_role_ddl(role regrole, pretty boolean DEFAULT false, memberships boolean DEFAULT true) pg_get_tablespace_ddl(tablespace oid/name, pretty boolean DEFAULT false, owner boolean DEFAULT true) pg_get_database_ddl(db regdatabase, pretty boolean DEFAULT false, owner boolean DEFAULT true, tablespace boolean DEFAULT true) This provides type safety at the SQL level, allows named-argument calling syntax (pretty => true), removes the runtime string-parsing machinery (DdlOption, parse_ddl_options) in favour of direct PG_GETARG_BOOL() calls, and allows the functions to be marked STRICT. While we're here, I added an extra TAP test for pg_get_database(owner => false, ...) Catalog version bumped. Author: Jelte Fennema-Nio <postgres@jeltef.nl> Discussion: https://postgr.es/m/DHM6C7SLS4BN.1WW9Z4PRPN0VJ@jeltef.nl (and on Discord)
If a "char" column has a statistics histogram, scalarineqsel() would fail with "cache lookup failed for collation 0". Avoid the failing lookup by acting as though the collation is "C". Prior to commit 06421b0, this code didn't fail because lc_collate_is_c() intentionally didn't spit up on InvalidOid. It did act differently though: it would take the non-C-collation code path and hence apply strxfrm using libc's prevailing locale. But that seems like the wrong thing for a non-collatable comparison, so let's not resurrect that aspect. Author: Feng Wu <wufengwufengwufeng@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CACK3muq6s-O1Wc3w4dRL1Fe8YQ-Fz1zJbezeQwhuLgNxGNEFiA@mail.gmail.com Backpatch-through: 18
Use underscores consistent across the varlistentry attributes in config.sgml. Inconsistencies found using Claude, verified by the reporter. Reported-by: Bill Kim <billkimjh@gmail.com> Reviewed-by: Peter Smith <smithpb2250@gmail.com> Discussion: https://postgr.es/m/CAMQXxchB0ZfMHyk+Ji-=s3hkqh0_XyuKiaNLRgvatvndSt3KNw@mail.gmail.com
Commit b7b27eb, which added foreign-key fast-path batching to ri_triggers.c, registered ri_FastPathXactCallback() via RegisterXactCallback() to clear the fast-path batching state at end of transaction. RegisterXactCallback() is documented as intended for dynamically loaded modules; built-in code is supposed to hardwire its end-of-xact hooks into xact.c, mainly so callback ordering can be controlled where it matters (see the header comment on RegisterXactCallback()). Convert the callback into a plain AtEOXact_RI() function and call it directly from CommitTransaction(), PrepareTransaction() and AbortTransaction(), alongside the other AtEOXact_* cleanup steps, and drop the RegisterXactCallback() registration. Like the other AtEOXact_* routines, AtEOXact_RI() takes an isCommit argument and treats the two paths differently. On commit or prepare the fast-path cache must already have been flushed and torn down by the after-trigger batch callback, so a surviving cache indicates a trigger batch was never flushed -- which would have silently skipped FK checks -- and draws an Assert plus a WARNING. On abort a surviving cache is expected (a flush may have errored out partway) and is simply reset. There is no ordering dependency here: AtEOXact_RI() only resets backend-local static state (the cache pointer, the callback-registered flag, and the in-flush guard). It touches no relations, locks, buffers or catalogs, so its position relative to ResourceOwnerRelease() and the surrounding AtEOXact_* calls does not matter. On a normal commit the fast-path cache has already been flushed and torn down by ri_FastPathEndBatch() (an AfterTriggerBatchCallback fired from AfterTriggerFireDeferred(), well before any end-of-xact callback), so the reset is a no-op; its real job is the abort path, where teardown may not have run and the static pointers would otherwise dangle into the next transaction. The cache memory itself lives in TopTransactionContext and is freed by the end-of-transaction memory-context reset on both paths. The companion RegisterSubXactCallback() use from b7b27eb was already removed by commit 4113873, which confined fast-path batching to the top transaction level, so only the RegisterXactCallback() use remained. Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Discussion: https://postgr.es/m/ajypPeEWceXRGAEW@bdtpg
…ng objects PL/Python and its hstore and jsonb transforms build SQL values from Python containers by calling Python C API functions that can return NULL, and in several places the result was used without first checking it. On the sequence side, PySequence_GetItem() is used when converting a returned sequence into a SQL array or composite value, when reading the argument list passed to plpy.execute() or plpy.cursor(), and when reading the list of type names given to plpy.prepare(). On the mapping side, the hstore and jsonb transforms call PyMapping_Size() and PyMapping_Items() and then index the result with PyList_GetItem() and PyTuple_GetItem(). All of these return NULL (or -1), with a Python exception set, for a broken object: for example one whose __getitem__() or items() raises, or which reports a length that disagrees with what it actually yields. The unchecked result was then dereferenced, crashing the backend. Fix this by checking the result of each call and reporting a regular error if it failed, so that the underlying Python exception is surfaced instead of taking down the session. Author: Richard Guo <guofenglinux@gmail.com> Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com> Discussion: https://postgr.es/m/CAMbWs49BKM9wP6m8bCXEpHwQKp7usvOGV6Jf=J7FYr_BCpxLqg@mail.gmail.com Backpatch-through: 14
While on it, let's add links pointing to the set of SQL commands generated by these functions. The descriptions of the functions are exactly the same, just moved around. Author: Peter Smith <smithpb2250@gmail.com> Reviewed-by: Ian Lawrence Barwick <barwick@gmail.com> Discussion: https://postgr.es/m/CAHut+Pun9Z8qZFJTa9fLgdhM=Cip9d-cnx2YXDW6eFrSwbQj1g@mail.gmail.com
Treat copy_file_range() return value of zero as an error: it indicates that no bytes could be copied (perhaps the source file is shorter than expected), and the existing retry loop would otherwise spin forever since nwritten would never reach BLCKSZ. The other uses of copy_file_range() in the tree don't have this problem. Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com> Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Reviewed-by: Yingying Chen <cyy9255@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/3208cf7a-c7f3-41eb-92f6-33cbeff4df40%40eisentraut.org
It is not clear how the implicit condition of FOR PORTION OF should interact with the use of a cursor. Normally, we forbid combining WHERE CURRENT OF with other WHERE conditions. The SQL standard only includes FOR PORTION OF with <update statement: searched> and <delete statement: searched>, not <update statement: positioned> or <delete statement: positioned>, so it is easy for us to exclude the functionality, at least for now. Author: Paul A. Jungwirth <pj@illuminatedcomputing.com> Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUEKPexUYsH4qeU8_o1jqKsUkEWca1keS6n21shgG1g%2BA%40mail.gmail.com
Replace typedefs.list with the authoritative list from our buildfarm, and run pgindent using that.
This is required before the creation of a new branch. pgindent is clean, as well as is reformat-dat-files. perltidy version is v20230309, as documented in pgindent's README.
Let the hacking begin ...
statatt_build_stavalues() and array_in_safe() have been relying on InitFunctionCallInfoData() with a locally-filled state to call a data type input function. InputFunctionCallSafe() can be used to achieve the same job, simplifying some code. This fixes an over-allocation of FunctionCallInfoBaseData done in statatt_build_stavalues(), where there was space for 8 elements but only 3 were needed. The over-allocation exists since REL_18_STABLE, and was harmless in practice. While on it, fix some comments for both routines, where elemtypid was mentioned. Backpatch down to v19. This code has been reworked during the last development cycle while working on the restore of extended statistics, so this keeps the code consistent across all branches. Author: Jian He <jian.universality@gmail.com> Author: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CACJufxEGah9PaiTQ=cG14GMMBsUQ3ohGct9tdSwbMQPQ0-nbbQ@mail.gmail.com Backpatch-through: 19
Previously, if an unlogged sequence was created on the primary and
replicated to a standby, reading the sequence after promoting the
standby (for example, with nextval()) could trigger the following
assertion failure:
TRAP: failed Assert("((const PageHeaderData *) page)->pd_special >= SizeOfPageHeaderData")
In non-assert builds, the same operation could instead fail with an
error such as:
ERROR: bad magic number in sequence
The problem was that seq_redo() updated the init fork page in shared
buffers but did not flush it to disk. During promotion,
ResetUnloggedRelations() recreates the main fork of unlogged
relations by copying the init fork from disk, bypassing shared
buffers. As a result, the main fork could be recreated from a stale
init fork instead of the WAL-replayed page.
Fix this by introducing a helper to flush init fork buffers
immediately, and make seq_redo() use it. As a result, the main fork
of an unlogged sequence is recreated from the up-to-date init fork on
disk, allowing the unlogged sequence to be read successfully after
standby promotion.
Backpatch to v15, where unlogged sequences were introduced.
Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Discussion: https://postgr.es/m/CAHGQGwH1Ssze3XM6wjoTjSLVOR041c6xP+vsdLP951=w8oG8bA@mail.gmail.com
Backpatch-through: 15
Commit 419ce13 accidentally left a stray blank line in ParseFuncOrColumn(). Remove it. No functional change. Author: Henson Choi <assam258@gmail.com> Discussion: https://postgr.es/m/CAAAe_zDLBkZFXXCgR_-NuaeW+aUXUtuDoSgg-2QRz+b2g7G4BA@mail.gmail.com Backpatch-through: 19
LockBufferForCleanup() acquires the exclusive content lock, checks the buffer's shared pin count, and, if other pins remain, registers itself as the BM_PIN_COUNT_WAITER before waiting for an unpin notification. Since commits 5310fac and c75ebc6, however, a shared buffer pin can be released while BM_LOCKED is set, introducing the following race: - LockBufferForCleanup() observes a refcount greater than one. - Before it sets BM_PIN_COUNT_WAITER, another backend releases the last conflicting pin. - Since BM_PIN_COUNT_WAITER is not yet set, no wakeup is sent. - LockBufferForCleanup() then sets BM_PIN_COUNT_WAITER and goes to sleep, even though only its own pin remains. As a result, LockBufferForCleanup() can sleep indefinitely because the wakeup corresponding to the last conflicting unpin has already been missed. Fix this by setting BM_PIN_COUNT_WAITER while holding the buffer header lock, then rechecking the refcount before releasing the content lock. If only our pin remains, clear the waiter state and proceed without sleeping. Otherwise, wait as before. This issue was reported by buildfarm member skink, where it manifested as intermittent timeouts in 048_vacuum_horizon_floor.pl. Backpatch to v19, where commits 5310fac and c75ebc6 introduced the race. Reported-by: Alexander Lakhin <exclusion@gmail.com> Author: Xuneng Zhou <xunengzhou@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Fujii Masao <masao.fujii@gmail.com> Discussion: https://postgr.es/m/7685519a-0bf9-4e17-93ca-7e3aa10fa29c@gmail.com Backpatch-through: 19
Commit b380a56 removed a paragraph, but two of the paragraph's three sentences remained relevant. Backpatch-through: 19
Other statistics views (pg_stat_io, pg_stat_database, etc.) use float8 for all measured-time columns, the new pg_stat_lock standing out as an outlier by using bigint. This commit aligns pg_stat_lock with the other stats views for consistency. Like pg_stat_io, the time is stored in microseconds, and is displayed in milliseconds with a conversion done when the view is queried. While on it, replace a use of "long" by PgStat_Counter, the former could overflow for large wait times where sizeof(long) is 4 bytes (aka WIN32). Bump catalog version. Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com> Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CAHza6qerEiQehrbW5xaXyxvR0qJe3KBX1R4kocDz1+7Ygu8x-g@mail.gmail.com Backpatch-through: 19
A placeholder %s is now used instead of the GUC names in the error string of this routine. This is going to be useful for a follow-up patch, where we will be able to reuse the same string, hence reducing the translation work. Based on a suggestion by me. Author: Baji Shaik <baji.pgdev@gmail.com> Discussion: https://postgr.es/m/ajnhfw84reaXgjfO@paquier.xyz
This commit extracts the tuple-building logic from pg_stat_get_lock() into a new static helper pg_stat_lock_build_tuples(). This is in preparation for a follow-up patch, to add support for backend-level lock stats, which will reuse the same helper. This change follows the pattern established by pg_stat_io_build_tuples() for IO stats and pg_stat_wal_build_tuple() for WAL stats. Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Tatsuya Kawata <kawatatatsuya0913@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Tristan Partin <tristan@partin.io> Reviewed-by: Rui Zhao <zhaorui126@gmail.com> Discussion: https://postgr.es/m/aiAzEY+cMQb/W8yu@bdtpg
This commit adds per-backend lock statistics, providing the same information as pg_stat_lock. It is now possible to retrieve those stats (lock wait counts, wait times, and fast-path exceeded count) on a per-backend basis. This data can be retrieved with a new system function called pg_stat_get_backend_lock(), that returns one tuple per lock type based on the PID provided in input. Like pg_stat_get_backend_io(), this is useful if joined with pg_stat_activity to get a live picture of the locks behavior for each running backend. pgstat_flush_backend() gains a new flag value, able to control the flush of the lock stats. This commit is straight-forward, relying on the infrastructure provided by 9aea73f (backend-level pgstats). Bump catalog version. No need to touch PGSTAT_FILE_FORMAT_ID as backend statistics are never written to disk. Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Tatsuya Kawata <kawatatatsuya0913@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Tristan Partin <tristan@partin.io> Reviewed-by: Rui Zhao <zhaorui126@gmail.com> Discussion: https://postgr.es/m/aiAzEY+cMQb/W8yu@bdtpg
Fixup for commit 8a27d41, which converted many functions to use "const Datum *" instead of "Datum *", including some SPI functions. For SPI_cursor_open(), the code was updated but not the documentation. For SPI_cursor_open_with_args(), the documentation was updated but not the code. (Possibly, these two were confused with each other.) Also, SPI_execp() and SPI_modifytuple() were not updated, even though they are closely related to the functions touched by the previous commit and now look inconsistent. Fix all these. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/86b5162f-c472-40fa-997b-0450dece1dec%40eisentraut.org
This changes the argtypes argument of SPI_prepare(), SPI_prepare_cursor(), SPI_cursor_open_with_args(), and SPI_execute_with_args() from Oid *argtypes to const Oid *argtypes. The underlying functions were already receptive to that, so this doesn't require any significant changes beyond the function signatures and some internal variables. Commit 28972b6 recently introduced a case where a const had to be cast away before calling these functions. This is fixed here. In passing, make a very similar const addition to SPI_modifytuple(). Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Ewan Young <kdbase.hack@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/86b5162f-c472-40fa-997b-0450dece1dec%40eisentraut.org
This code appears to be an artifact from commit b64d92f that was never used for anything. Reviewed-by: Corey Huinker <corey.huinker@gmail.com> Discussion: https://postgr.es/m/afouZUH_eUkIj4i4%40nathan
In various places we depend on compiler-defined macros like __x86_64__ to guard CPU-type-specific code. However, those macros aren't very well standardized; in particular, it emerges that MSVC doesn't define any of the ones gcc does, but has its own. We were not coping with that consistently, with the result that we're missing some useful CPU-dependent optimizations in MSVC builds. There are also some places that are checking randomly-different spellings that may have been the only ones recognized by some old compilers, but we weren't doing that consistently either. Let's standardize on using gcc's long-form spellings (with trailing underscores), after putting a stanza into c.h that ensures that these spellings are defined even when the compiler provides some other one. I put an "#else #error" branch into the c.h addition so that we'll get an error if the compiler provides none of the symbols we're expecting. That might be best removed in the end, since it might annoy people trying to port to some new CPU type. But for testing this it seems like a good idea, in case we've missed some common variant spelling. In addition to enabling some optimizations we previously missed on MSVC, this cleans up a thinko. Several places used "_M_X64" in the apparent belief that that's MSVC's equivalent to __x86_64__, but it's not: it will also get defined on some but not all ARM64 builds. Also, guard the x86_feature_available() stuff in pg_cpu.[hc] with #if defined(__x86_64__) || defined(__i386__) which seems like a more natural way of specifying what it applies to. This builds on some previous work by Thomas Munro, but it requires much less code churn because it re-uses gcc's names for the CPU-type macros instead of inventing our own. Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CA+hUKGL8Hs-phHPugrWM=5dAkcT897rXyazYzLw-Szxnzgx-rA@mail.gmail.com Discussion: https://postgr.es/m/3035145.1780503430@sss.pgh.pa.us
The existing description says the ranges of merged range-partitions "must be adjacent" only under the heading "If the DEFAULT partition is not in the list of merged partitions". That could be misread as a restriction tied to the presence of a default partition. In fact, merging non-adjacent ranges is rejected regardless of whether the partitioned table has a default partition; spell that out explicitly. Also, this commit removes a small redundancy in the documentation sentence stating that "merged range-partitions" are "to be merged". Reported-by: Justin Pryzby <pryzby@telsasoft.com> Discussion: https://postgr.es/m/aj6BPoziSb-F8aJz%40pryzbyj2023 Reported-by: Pavel Borisov <pashkin.elfe@gmail.com> Backpatch-through: 19
We previously allowed this, but it leads to odd behaviors, basically because putting a SRF there is inconsistent with the principle that a window function doesn't change the number of rows in the query result. There doesn't seem to be a strong reason to try to make such cases behave consistently. Users should put their SRFs in lateral FROM clauses instead. This issue has been sitting on the back burner for multiple years now, partially because it didn't seem wise to back-patch such a change. Let's squeeze it into v19 before it's too late. Bug: #17502 Bug: #19535 Reported-by: Daniel Farkaš <daniel.farkas@datoris.com> Reported-by: Qifan Liu <imchifan@163.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: David Rowley <dgrowleyml@gmail.com> Discussion: https://postgr.es/m/17502-281a7aaacfaa872a@postgresql.org Discussion: https://postgr.es/m/19535-376081d7cc07c86d@postgresql.org Backpatch-through: 19
This replaces the use of the 1024 byte jumble buffer and use of hash_any_extended (Jenkins-style hash function) for query id jumbling with the newer fasthash_ API that avoids the use of a separate buffer, and carries less performance overhead. Both hash function are non-cryptographic hashes that optimize for performance, but fasthash is the more modern function and passes the SMhasher test suite for hash collisions. Author: Lukas Fittl <lukas@fittl.com> Reviewed-by: Discussion:
78ab5f6 to
d8312d9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.