Files
Vinod Sridharan 3f9a507562 Merged PR 1539950: [OSS] Move helio_api and helio_distributed sources under documentdb
### Does this PR have any customer impact?
No

### Type (Feature, Refactoring, Bugfix, DevOps, Testing, Perf, etc)
Refactor

### Does it involve schema level changes? (Table, Column, Index, UDF, etc level changes)
No

### Are you introducing any new config? If yes, do you have tests with and without them being set?
No
### Release Note (Refer [Template](../docs/release_notes/pgmongo_template.md))

### Description
Move source files under new directory.

----
#### AI description  (iteration 1)
#### PR Classification
Code reorganization

#### PR Summary
This pull request moves the `helio_api` and `helio_distributed` sources under the `documentdb` directory, updating references and initialization logic accordingly.
- Added `pg_documentdb.c` for initializing the `pg_documentdb` extension.
- Added `documentdb_distributed.c` for initializing the `pg_documentdb_distributed` extension.
- Updated `validate_helio_extension_state.sh` to include new checks for `documentdb`.
- Moved `helio_api_extension_version.c` to `documentdb_extension_version.c` without code changes.
- Updated various `Makefile` configurations to reflect the new directory structure and dependencies.
2025-01-15 07:48:39 +00:00

141 lines
5.7 KiB
C

/*-------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* include/utils/query_utils.h
*
* Utilities to execute a command/query.
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
#include <utils/array.h>
#include <executor/spi.h>
#ifndef QUERY_UTILS_H
#define QUERY_UTILS_H
/*
* Execute a query within the current transaction and return the first datum
* of the first tuple returned by given query (if any).
*
* Rollbacking or aborting the current transaction / subtransaction is
* guaranteed to rollback the query that has been executed even if query
* execution has been completed already.
*/
Datum ExtensionExecuteQueryViaSPI(const char *query, bool readOnly, int expectedSPIOK,
bool *isNull);
void ExtensionExecuteMultiValueQueryViaSPI(const char *query, bool readOnly,
int expectedSPIOK, Datum *datums,
bool *isNull, int numValues);
Datum ExtensionExecuteQueryWithArgsViaSPI(const char *query, int nargs, Oid *argTypes,
Datum *argValues, char *argNulls,
bool readOnly, int expectedSPIOK,
bool *isNull);
Datum ExtensionExecuteCappedQueryWithArgsViaSPI(const char *query, int nargs,
Oid *argTypes,
Datum *argValues, char *argNulls,
bool readOnly, int expectedSPIOK,
bool *isNull, int statementTimeout,
int lockTimeout);
void ExtensionExecuteMultiValueQueryWithArgsViaSPI(const char *query, int nargs,
Oid *argTypes, Datum *argValues,
char *argNulls, bool readOnly,
int expectedSPIOK, Datum *datums,
bool *isNull, int numValues);
uint64 ExtensionExecuteCappedStatementWithArgsViaSPI(const char *query, int nargs,
Oid *argTypes,
Datum *argValues, char *argNulls,
bool readOnly, int expectedSPIOK,
int statementTimeout, int
lockTimeout);
/*
* Execute a query outside the current transaction and return the first
* attribute of the first tuple returned by given query (if any).
*
* After the execution of given query completes, it cannot be rollbacked even
* if current transaction / subtransaction rollbacks or aborts.
*
* Otherwise, i.e.: if this function didn't return yet, then there is still
* a chance to cancel the query when rollbacking or aborting the current the
* transaction / subtransaction since the abort handlers in
* TransactionCallback & SubTransactionCallback will then try
* cancelling the query. However, it is still not guaranteed that given query
* will be rollbacked. This is because;
* i) The transaction that we started over the libpq connection might got
* committed already, i.e.: remote transaction is not active anymore.
* ii) Theoretically, connection establishment to localhost might still fail
* while trying to send the cancellation.
*
* [1] Why can using a libpq connection might cause an undetectable deadlock ?
* (Please keep in mind that "s" means "session" and "r" means "resource"
* in this scenario.)
*
* Suppose that s1 acquired r1 and waits for r2, and s2 acquired r2 and
* waits for r1. In that case, postgres would throw an error telling that
* those two sessions entered into a deadlock. Or, if those resources belong
* to different Citus nodes (coordinator / MX worker), then Citus would
* report this as a "distributed deadlock" instead of postgres.
*
* And now let's consider another scenario. Suppose that s1 acquired r1
* and the libpq connection (initiated via ExtensionExecuteQueryOnLocalhostViaLibPQ())
* that s1 is waiting for is waiting for r2, and s2 acquired r2 and it
* waits for r1. Here, s2 waits for s1 to release a resource, and s1 waits
* for the libpq to finish its IO; and that libpq connection is waiting for
* s2 to release a resource. Given the wait-triangle here, one could expect
* postgres or Citus to detect this as a deadlock condition where three
* processes involved; but this is not the case. This is because, postgres
* doesn't take the connection-IO waits into the account (even if they are
* local) when detecting deadlock conditions and such a scenario would cause
* those processes to wait for each other indefinitely. For this reason, callers
* should be careful about such cases when using ExtensionExecuteQueryViaLibPQ()
* instead of ExtensionExecuteQueryViaSPI() or such.
*/
char * ExtensionExecuteQueryOnLocalhostViaLibPQ(char *query);
/*
* Same as ExtensionExecuteQueryOnLocalhostViaLibPQ, but connects as specific user.
*/
char * ExtensionExecuteQueryAsUserOnLocalhostViaLibPQ(char *query, const Oid userOid,
bool useSerialExecution);
/* Same as ExtensionExecuteQueryAsUserOnLocalhostViaLibPQ, but it allows to execute parameterized query */
char * ExtensionExecuteQueryWithArgsAsUserOnLocalhostViaLibPQ(char *query, const Oid
userOid, int nParams,
Oid *paramTypes, const
char **parameterValues);
/*
* Helper method to create a string query using a variable number
* of arguments - similar to doing
* StringInfo s = makeStringInfo();
* appendStringInfo(s, "queryFormat", args);
* return s->data;
*/
pg_attribute_printf(1, 2) inline static const char *
FormatSqlQuery(const char *queryFormat, ...)
{
StringInfoData cmdbuf;
initStringInfo(&cmdbuf);
for (;;)
{
va_list args;
int needed;
va_start(args, queryFormat);
needed = appendStringInfoVA(&cmdbuf, queryFormat, args);
va_end(args);
if (needed == 0)
{
break; /* success */
}
enlargeStringInfo(&cmdbuf, needed);
}
return cmdbuf.data;
}
#endif