add copy of cosmos node.js SDK as local dependency

This commit is contained in:
Theo van Kraay
2024-08-31 16:44:42 +01:00
committed by Chris Anderson
parent 679e4e56df
commit 2afb2d82e4
4 changed files with 790 additions and 694 deletions
@@ -7,7 +7,7 @@ import { StatusCodes, SubStatusCodes } from "../common";
import { MetadataLookUpType } from "../CosmosDiagnostics"; import { MetadataLookUpType } from "../CosmosDiagnostics";
import { CosmosDbDiagnosticLevel } from "../diagnostics/CosmosDbDiagnosticLevel"; import { CosmosDbDiagnosticLevel } from "../diagnostics/CosmosDbDiagnosticLevel";
import { DiagnosticNodeInternal, DiagnosticNodeType } from "../diagnostics/DiagnosticNodeInternal"; import { DiagnosticNodeInternal, DiagnosticNodeType } from "../diagnostics/DiagnosticNodeInternal";
import { RUCapPerOperationExceededErrorCode, } from "../request/RUCapPerOperationExceededError"; import { RUCapPerOperationExceededErrorCode } from "../request/RUCapPerOperationExceededError";
import { QueryRange } from "../routing/QueryRange"; import { QueryRange } from "../routing/QueryRange";
import { SmartRoutingMapProvider } from "../routing/smartRoutingMapProvider"; import { SmartRoutingMapProvider } from "../routing/smartRoutingMapProvider";
import { addDignosticChild } from "../utils/diagnostics"; import { addDignosticChild } from "../utils/diagnostics";
@@ -52,7 +52,11 @@ export class ParallelQueryExecutionContextBase {
this.partitionedQueryExecutionInfo = partitionedQueryExecutionInfo; this.partitionedQueryExecutionInfo = partitionedQueryExecutionInfo;
this.diagnosticNodeWrapper = { this.diagnosticNodeWrapper = {
consumed: false, consumed: false,
diagnosticNode: new DiagnosticNodeInternal(clientContext.diagnosticLevel, DiagnosticNodeType.PARALLEL_QUERY_NODE, null), diagnosticNode: new DiagnosticNodeInternal(
clientContext.diagnosticLevel,
DiagnosticNodeType.PARALLEL_QUERY_NODE,
null,
),
}; };
this.diagnosticNodeWrapper.diagnosticNode.addData({ stateful: true }); this.diagnosticNodeWrapper.diagnosticNode.addData({ stateful: true });
this.err = undefined; this.err = undefined;
@@ -112,7 +116,10 @@ export class ParallelQueryExecutionContextBase {
// Create the replacement documentProducers // Create the replacement documentProducers
replacementPartitionKeyRanges.forEach((partitionKeyRange) => { replacementPartitionKeyRanges.forEach((partitionKeyRange) => {
// Create replacment document producers with the parent's continuationToken // Create replacment document producers with the parent's continuationToken
const replacementDocumentProducer = this._createTargetPartitionQueryExecutionContext(partitionKeyRange, parentDocumentProducer.continuationToken); const replacementDocumentProducer = this._createTargetPartitionQueryExecutionContext(
partitionKeyRange,
parentDocumentProducer.continuationToken,
);
replacementDocumentProducers.push(replacementDocumentProducer); replacementDocumentProducers.push(replacementDocumentProducer);
}); });
// We need to check if the documentProducers even has anything left to fetch from before enqueing them // We need to check if the documentProducers even has anything left to fetch from before enqueing them
@@ -121,14 +128,12 @@ export class ParallelQueryExecutionContextBase {
const { result: afterItem } = await documentProducerToCheck.current(diagnosticNode); const { result: afterItem } = await documentProducerToCheck.current(diagnosticNode);
if (afterItem === undefined) { if (afterItem === undefined) {
// no more results left in this document producer, so we don't enqueue it // no more results left in this document producer, so we don't enqueue it
} } else {
else {
// Safe to put document producer back in the queue // Safe to put document producer back in the queue
this.orderByPQ.enq(documentProducerToCheck); this.orderByPQ.enq(documentProducerToCheck);
} }
await checkNextDocumentProducerCallback(); await checkNextDocumentProducerCallback();
} } catch (err) {
catch (err) {
this.err = err; this.err = err;
return; return;
} }
@@ -140,25 +145,25 @@ export class ParallelQueryExecutionContextBase {
await checkAndEnqueueDocumentProducer(replacementDocumentProducer, async () => { await checkAndEnqueueDocumentProducer(replacementDocumentProducer, async () => {
await checkAndEnqueueDocumentProducers(rdp); await checkAndEnqueueDocumentProducers(rdp);
}); });
} } else {
else {
// reexecutes the originFunction with the corrrected executionContext // reexecutes the originFunction with the corrrected executionContext
return originFunction(); return originFunction();
} }
}; };
// Invoke the recursive function to get the ball rolling // Invoke the recursive function to get the ball rolling
await checkAndEnqueueDocumentProducers(replacementDocumentProducers); await checkAndEnqueueDocumentProducers(replacementDocumentProducers);
} } catch (err) {
catch (err) {
this.err = err; this.err = err;
throw err; throw err;
} }
} }
static _needPartitionKeyRangeCacheRefresh(error) { static _needPartitionKeyRangeCacheRefresh(error) {
// TODO: any error // TODO: any error
return (error.code === StatusCodes.Gone && return (
error.code === StatusCodes.Gone &&
"substatus" in error && "substatus" in error &&
error["substatus"] === SubStatusCodes.PartitionKeyRangeGone); error["substatus"] === SubStatusCodes.PartitionKeyRangeGone
);
} }
/** /**
* Checks to see if the executionContext needs to be repaired. * Checks to see if the executionContext needs to be repaired.
@@ -171,13 +176,15 @@ export class ParallelQueryExecutionContextBase {
try { try {
await documentProducer.current(diagnosticNode, operationOptions, ruConsumedManager); await documentProducer.current(diagnosticNode, operationOptions, ruConsumedManager);
elseCallback(); elseCallback();
} } catch (err) {
catch (err) {
if (ParallelQueryExecutionContextBase._needPartitionKeyRangeCacheRefresh(err)) { if (ParallelQueryExecutionContextBase._needPartitionKeyRangeCacheRefresh(err)) {
// Split has happened so we need to repair execution context before continueing // Split has happened so we need to repair execution context before continueing
return addDignosticChild((childNode) => this._repairExecutionContext(childNode, ifCallback), diagnosticNode, DiagnosticNodeType.QUERY_REPAIR_NODE); return addDignosticChild(
} (childNode) => this._repairExecutionContext(childNode, ifCallback),
else { diagnosticNode,
DiagnosticNodeType.QUERY_REPAIR_NODE,
);
} else {
// Something actually bad happened ... // Something actually bad happened ...
this.err = err; this.err = err;
throw err; throw err;
@@ -199,8 +206,7 @@ export class ParallelQueryExecutionContextBase {
try { try {
await this._createDocumentProducersAndFillUpPriorityQueue(operationOptions, ruConsumedManager); await this._createDocumentProducersAndFillUpPriorityQueue(operationOptions, ruConsumedManager);
this.initializedPriorityQueue = true; this.initializedPriorityQueue = true;
} } catch (err) {
catch (err) {
this.err = err; this.err = err;
// release the lock before invoking callback // release the lock before invoking callback
this.nextItemfetchSemaphore.leave(); this.nextItemfetchSemaphore.leave();
@@ -209,11 +215,14 @@ export class ParallelQueryExecutionContextBase {
} }
} }
if (!this.diagnosticNodeWrapper.consumed) { if (!this.diagnosticNodeWrapper.consumed) {
diagnosticNode.addChildNode(this.diagnosticNodeWrapper.diagnosticNode, CosmosDbDiagnosticLevel.debug, MetadataLookUpType.QueryPlanLookUp); diagnosticNode.addChildNode(
this.diagnosticNodeWrapper.diagnosticNode,
CosmosDbDiagnosticLevel.debug,
MetadataLookUpType.QueryPlanLookUp,
);
this.diagnosticNodeWrapper.diagnosticNode = undefined; this.diagnosticNodeWrapper.diagnosticNode = undefined;
this.diagnosticNodeWrapper.consumed = true; this.diagnosticNodeWrapper.consumed = true;
} } else {
else {
this.diagnosticNodeWrapper.diagnosticNode = diagnosticNode; this.diagnosticNodeWrapper.diagnosticNode = diagnosticNode;
} }
// NOTE: lock must be released before invoking quitting // NOTE: lock must be released before invoking quitting
@@ -244,8 +253,7 @@ export class ParallelQueryExecutionContextBase {
let documentProducer; let documentProducer;
try { try {
documentProducer = this.orderByPQ.deq(); documentProducer = this.orderByPQ.deq();
} } catch (e) {
catch (e) {
// if comparing elements of the priority queue throws exception // if comparing elements of the priority queue throws exception
// set that error and return error // set that error and return error
this.err = e; this.err = e;
@@ -275,13 +283,11 @@ export class ParallelQueryExecutionContextBase {
headers: this._getAndResetActiveResponseHeaders(), headers: this._getAndResetActiveResponseHeaders(),
}); });
} }
} } catch (err) {
catch (err) {
if (err.code === RUCapPerOperationExceededErrorCode) { if (err.code === RUCapPerOperationExceededErrorCode) {
this._updateErrorObjectWithBufferedData(err); this._updateErrorObjectWithBufferedData(err);
this.err = err; this.err = err;
} } else {
else {
this.err = new Error(`Extracted DocumentProducer from the priority queue fails to get the \ this.err = new Error(`Extracted DocumentProducer from the priority queue fails to get the \
buffered item. Due to ${JSON.stringify(err)}`); buffered item. Due to ${JSON.stringify(err)}`);
this.err.headers = this._getAndResetActiveResponseHeaders(); this.err.headers = this._getAndResetActiveResponseHeaders();
@@ -294,44 +300,42 @@ export class ParallelQueryExecutionContextBase {
// we need to put back the document producer to the queue if it has more elements. // we need to put back the document producer to the queue if it has more elements.
// the lock will be released after we know document producer must be put back in the queue or not // the lock will be released after we know document producer must be put back in the queue or not
try { try {
const { result: afterItem, headers: otherHeaders } = await documentProducer.current(diagnosticNode, operationOptions, ruConsumedManager); const { result: afterItem, headers: otherHeaders } = await documentProducer.current(
diagnosticNode,
operationOptions,
ruConsumedManager,
);
this._mergeWithActiveResponseHeaders(otherHeaders); this._mergeWithActiveResponseHeaders(otherHeaders);
if (afterItem === undefined) { if (afterItem === undefined) {
// no more results is left in this document producer // no more results is left in this document producer
} } else {
else {
try { try {
const headItem = documentProducer.fetchResults[0]; const headItem = documentProducer.fetchResults[0];
if (typeof headItem === "undefined") { if (typeof headItem === "undefined") {
throw new Error("Extracted DocumentProducer from PQ is invalid state with no result!"); throw new Error("Extracted DocumentProducer from PQ is invalid state with no result!");
} }
this.orderByPQ.enq(documentProducer); this.orderByPQ.enq(documentProducer);
} } catch (e) {
catch (e) {
// if comparing elements in priority queue throws exception // if comparing elements in priority queue throws exception
// set error // set error
this.err = e; this.err = e;
} }
} }
} } catch (err) {
catch (err) {
if (ParallelQueryExecutionContextBase._needPartitionKeyRangeCacheRefresh(err)) { if (ParallelQueryExecutionContextBase._needPartitionKeyRangeCacheRefresh(err)) {
// We want the document producer enqueued // We want the document producer enqueued
// So that later parts of the code can repair the execution context // So that later parts of the code can repair the execution context
this.orderByPQ.enq(documentProducer); this.orderByPQ.enq(documentProducer);
} } else if (err.code === RUCapPerOperationExceededErrorCode) {
else if (err.code === RUCapPerOperationExceededErrorCode) {
this._updateErrorObjectWithBufferedData(err); this._updateErrorObjectWithBufferedData(err);
this.err = err; this.err = err;
reject(this.err); reject(this.err);
} } else {
else {
// Something actually bad happened // Something actually bad happened
this.err = err; this.err = err;
reject(this.err); reject(this.err);
} }
} } finally {
finally {
// release the lock before returning // release the lock before returning
this.nextItemfetchSemaphore.leave(); this.nextItemfetchSemaphore.leave();
} }
@@ -370,8 +374,7 @@ export class ParallelQueryExecutionContextBase {
const query = this.query; const query = this.query;
if (typeof query === "string") { if (typeof query === "string") {
sqlQuerySpec = { query }; sqlQuerySpec = { query };
} } else {
else {
sqlQuerySpec = query; sqlQuerySpec = query;
} }
const formatPlaceHolder = "{documentdb-formattableorderbyquery-filter}"; const formatPlaceHolder = "{documentdb-formattableorderbyquery-filter}";
@@ -383,32 +386,42 @@ export class ParallelQueryExecutionContextBase {
} }
const options = Object.assign({}, this.options); const options = Object.assign({}, this.options);
options.continuationToken = continuationToken; options.continuationToken = continuationToken;
return new DocumentProducer(this.clientContext, this.collectionLink, sqlQuerySpec, partitionKeyTargetRange, options); return new DocumentProducer(
this.clientContext,
this.collectionLink,
sqlQuerySpec,
partitionKeyTargetRange,
options,
);
} }
async _createDocumentProducersAndFillUpPriorityQueue(operationOptions, ruConsumedManager) { async _createDocumentProducersAndFillUpPriorityQueue(operationOptions, ruConsumedManager) {
try { try {
const targetPartitionRanges = await this._onTargetPartitionRanges(); const targetPartitionRanges = await this._onTargetPartitionRanges();
const maxDegreeOfParallelism = this.options.maxDegreeOfParallelism === undefined || this.options.maxDegreeOfParallelism < 1 const maxDegreeOfParallelism =
this.options.maxDegreeOfParallelism === undefined || this.options.maxDegreeOfParallelism < 1
? targetPartitionRanges.length ? targetPartitionRanges.length
: Math.min(this.options.maxDegreeOfParallelism, targetPartitionRanges.length); : Math.min(this.options.maxDegreeOfParallelism, targetPartitionRanges.length);
logger.info("Query starting against " + logger.info(
"Query starting against " +
targetPartitionRanges.length + targetPartitionRanges.length +
" ranges with parallelism of " + " ranges with parallelism of " +
maxDegreeOfParallelism); maxDegreeOfParallelism,
);
let filteredPartitionKeyRanges = []; let filteredPartitionKeyRanges = [];
// The document producers generated from filteredPartitionKeyRanges // The document producers generated from filteredPartitionKeyRanges
const targetPartitionQueryExecutionContextList = []; const targetPartitionQueryExecutionContextList = [];
if (this.requestContinuation) { if (this.requestContinuation) {
throw new Error("Continuation tokens are not yet supported for cross partition queries"); throw new Error("Continuation tokens are not yet supported for cross partition queries");
} } else {
else {
filteredPartitionKeyRanges = targetPartitionRanges; filteredPartitionKeyRanges = targetPartitionRanges;
} }
// Create one documentProducer for each partitionTargetRange // Create one documentProducer for each partitionTargetRange
filteredPartitionKeyRanges.forEach((partitionTargetRange) => { filteredPartitionKeyRanges.forEach((partitionTargetRange) => {
// TODO: any partitionTargetRange // TODO: any partitionTargetRange
// no async callback // no async callback
targetPartitionQueryExecutionContextList.push(this._createTargetPartitionQueryExecutionContext(partitionTargetRange)); targetPartitionQueryExecutionContextList.push(
this._createTargetPartitionQueryExecutionContext(partitionTargetRange),
);
}); });
// Fill up our priority queue with documentProducers // Fill up our priority queue with documentProducers
let inProgressPromises = []; let inProgressPromises = [];
@@ -438,36 +451,36 @@ export class ParallelQueryExecutionContextBase {
} }
throw this.err; throw this.err;
} }
} } catch (err) {
catch (err) {
this.err = err; this.err = err;
throw err; throw err;
} }
} }
async _processAndEnqueueDocumentProducer(documentProducer, operationOptions, ruConsumedManager) { async _processAndEnqueueDocumentProducer(documentProducer, operationOptions, ruConsumedManager) {
try { try {
const { result: document, headers } = await documentProducer.current(this.getDiagnosticNode(), operationOptions, ruConsumedManager); const { result: document, headers } = await documentProducer.current(
this.getDiagnosticNode(),
operationOptions,
ruConsumedManager,
);
this._mergeWithActiveResponseHeaders(headers); this._mergeWithActiveResponseHeaders(headers);
if (document !== undefined) { if (document !== undefined) {
this.orderByPQ.enq(documentProducer); this.orderByPQ.enq(documentProducer);
} }
} } catch (err) {
catch (err) {
this._mergeWithActiveResponseHeaders(err.headers); this._mergeWithActiveResponseHeaders(err.headers);
this.err = err; this.err = err;
if (err.code === RUCapPerOperationExceededErrorCode) { if (err.code === RUCapPerOperationExceededErrorCode) {
// would be halting further execution of other promises // would be halting further execution of other promises
if (!this.ruCapExceededError) { if (!this.ruCapExceededError) {
this.ruCapExceededError = err; this.ruCapExceededError = err;
} } else {
else {
// merge the buffered items // merge the buffered items
if (err.fetchedResults) { if (err.fetchedResults) {
this.ruCapExceededError.fetchedResults.push(...err.fetchedResults); this.ruCapExceededError.fetchedResults.push(...err.fetchedResults);
} }
} }
} } else {
else {
throw err; throw err;
} }
} }
@@ -4,10 +4,15 @@ import { __asyncGenerator, __await } from "tslib";
import { getPathFromLink, ResourceType, RUConsumedManager, StatusCodes } from "./common"; import { getPathFromLink, ResourceType, RUConsumedManager, StatusCodes } from "./common";
import { MetadataLookUpType } from "./CosmosDiagnostics"; import { MetadataLookUpType } from "./CosmosDiagnostics";
import { DiagnosticNodeInternal, DiagnosticNodeType } from "./diagnostics/DiagnosticNodeInternal"; import { DiagnosticNodeInternal, DiagnosticNodeType } from "./diagnostics/DiagnosticNodeInternal";
import { DefaultQueryExecutionContext, getInitialHeader, mergeHeaders, PipelinedQueryExecutionContext, } from "./queryExecutionContext"; import {
DefaultQueryExecutionContext,
getInitialHeader,
mergeHeaders,
PipelinedQueryExecutionContext,
} from "./queryExecutionContext";
import { FeedResponse } from "./request/FeedResponse"; import { FeedResponse } from "./request/FeedResponse";
import { RUCapPerOperationExceededErrorCode } from "./request/RUCapPerOperationExceededError"; import { RUCapPerOperationExceededErrorCode } from "./request/RUCapPerOperationExceededError";
import { getEmptyCosmosDiagnostics, withDiagnostics, withMetadataDiagnostics, } from "./utils/diagnostics"; import { getEmptyCosmosDiagnostics, withDiagnostics, withMetadataDiagnostics } from "./utils/diagnostics";
/** /**
* Represents a QueryIterator Object, an implementation of feed or query response that enables * Represents a QueryIterator Object, an implementation of feed or query response that enables
* traversal and iterating over the response * traversal and iterating over the response
@@ -58,7 +63,11 @@ export class QueryIterator {
getAsyncIterator(options) { getAsyncIterator(options) {
return __asyncGenerator(this, arguments, function* getAsyncIterator_1() { return __asyncGenerator(this, arguments, function* getAsyncIterator_1() {
this.reset(); this.reset();
let diagnosticNode = new DiagnosticNodeInternal(this.clientContext.diagnosticLevel, DiagnosticNodeType.CLIENT_REQUEST_NODE, null); let diagnosticNode = new DiagnosticNodeInternal(
this.clientContext.diagnosticLevel,
DiagnosticNodeType.CLIENT_REQUEST_NODE,
null,
);
this.queryPlanPromise = this.fetchQueryPlan(diagnosticNode); this.queryPlanPromise = this.fetchQueryPlan(diagnosticNode);
let ruConsumedManager; let ruConsumedManager;
if (options && options.ruCapPerOperation) { if (options && options.ruCapPerOperation) {
@@ -68,23 +77,31 @@ export class QueryIterator {
let response; let response;
try { try {
response = yield __await(this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager)); response = yield __await(this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager));
} } catch (error) {
catch (error) {
if (this.needsQueryPlan(error)) { if (this.needsQueryPlan(error)) {
yield __await(this.createPipelinedExecutionContext()); yield __await(this.createPipelinedExecutionContext());
try { try {
response = yield __await(this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager)); response = yield __await(
} this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager),
catch (queryError) { );
} catch (queryError) {
this.handleSplitError(queryError); this.handleSplitError(queryError);
} }
} } else {
else {
throw error; throw error;
} }
} }
const feedResponse = new FeedResponse(response.result, response.headers, this.queryExecutionContext.hasMoreResults(), diagnosticNode.toDiagnostic(this.clientContext.getClientConfig())); const feedResponse = new FeedResponse(
diagnosticNode = new DiagnosticNodeInternal(this.clientContext.diagnosticLevel, DiagnosticNodeType.CLIENT_REQUEST_NODE, null); response.result,
response.headers,
this.queryExecutionContext.hasMoreResults(),
diagnosticNode.toDiagnostic(this.clientContext.getClientConfig()),
);
diagnosticNode = new DiagnosticNodeInternal(
this.clientContext.diagnosticLevel,
DiagnosticNodeType.CLIENT_REQUEST_NODE,
null,
);
if (response.result !== undefined) { if (response.result !== undefined) {
yield yield __await(feedResponse); yield yield __await(feedResponse);
} }
@@ -115,8 +132,7 @@ export class QueryIterator {
let response; let response;
try { try {
response = await this.toArrayImplementation(diagnosticNode, options); response = await this.toArrayImplementation(diagnosticNode, options);
} } catch (error) {
catch (error) {
this.handleSplitError(error); this.handleSplitError(error);
} }
return response; return response;
@@ -132,31 +148,37 @@ export class QueryIterator {
return withDiagnostics(async (diagnosticNode) => { return withDiagnostics(async (diagnosticNode) => {
// Enabling RU metrics for all the fetchNext operations // Enabling RU metrics for all the fetchNext operations
const ruConsumedManager = new RUConsumedManager(); const ruConsumedManager = new RUConsumedManager();
this.queryPlanPromise = withMetadataDiagnostics(async (metadataNode) => { this.queryPlanPromise = withMetadataDiagnostics(
async (metadataNode) => {
return this.fetchQueryPlan(metadataNode); return this.fetchQueryPlan(metadataNode);
}, diagnosticNode, MetadataLookUpType.QueryPlanLookUp); },
diagnosticNode,
MetadataLookUpType.QueryPlanLookUp,
);
if (!this.isInitialized) { if (!this.isInitialized) {
await this.init(); await this.init();
} }
let response; let response;
try { try {
response = await this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager); response = await this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager);
} } catch (error) {
catch (error) {
if (this.needsQueryPlan(error)) { if (this.needsQueryPlan(error)) {
await this.createPipelinedExecutionContext(); await this.createPipelinedExecutionContext();
try { try {
response = await this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager); response = await this.queryExecutionContext.fetchMore(diagnosticNode, options, ruConsumedManager);
} } catch (queryError) {
catch (queryError) {
this.handleSplitError(queryError); this.handleSplitError(queryError);
} }
} } else {
else {
throw error; throw error;
} }
} }
return new FeedResponse(response.result, response.headers, this.queryExecutionContext.hasMoreResults(), getEmptyCosmosDiagnostics()); return new FeedResponse(
response.result,
response.headers,
this.queryExecutionContext.hasMoreResults(),
getEmptyCosmosDiagnostics(),
);
}, this.clientContext); }, this.clientContext);
} }
/** /**
@@ -173,9 +195,13 @@ export class QueryIterator {
if (options && options.ruCapPerOperation) { if (options && options.ruCapPerOperation) {
ruConsumedManager = new RUConsumedManager(); ruConsumedManager = new RUConsumedManager();
} }
this.queryPlanPromise = withMetadataDiagnostics(async (metadataNode) => { this.queryPlanPromise = withMetadataDiagnostics(
async (metadataNode) => {
return this.fetchQueryPlan(metadataNode); return this.fetchQueryPlan(metadataNode);
}, diagnosticNode, MetadataLookUpType.QueryPlanLookUp); },
diagnosticNode,
MetadataLookUpType.QueryPlanLookUp,
);
// this.queryPlanPromise = this.fetchQueryPlan(diagnosticNode); // this.queryPlanPromise = this.fetchQueryPlan(diagnosticNode);
if (!this.isInitialized) { if (!this.isInitialized) {
await this.init(); await this.init();
@@ -184,20 +210,17 @@ export class QueryIterator {
let response; let response;
try { try {
response = await this.queryExecutionContext.nextItem(diagnosticNode, options, ruConsumedManager); response = await this.queryExecutionContext.nextItem(diagnosticNode, options, ruConsumedManager);
} } catch (error) {
catch (error) {
if (this.needsQueryPlan(error)) { if (this.needsQueryPlan(error)) {
await this.createPipelinedExecutionContext(); await this.createPipelinedExecutionContext();
response = await this.queryExecutionContext.nextItem(diagnosticNode, options, ruConsumedManager); response = await this.queryExecutionContext.nextItem(diagnosticNode, options, ruConsumedManager);
} } else if (error.code === RUCapPerOperationExceededErrorCode && error.fetchedResults) {
else if (error.code === RUCapPerOperationExceededErrorCode && error.fetchedResults) {
error.fetchedResults.forEach((item) => { error.fetchedResults.forEach((item) => {
this.fetchAllTempResources.push(item); this.fetchAllTempResources.push(item);
}); });
error.fetchedResults = this.fetchAllTempResources; error.fetchedResults = this.fetchAllTempResources;
throw error; throw error;
} } else {
else {
throw error; throw error;
} }
} }
@@ -205,16 +228,17 @@ export class QueryIterator {
// concatenate the results and fetch more // concatenate the results and fetch more
mergeHeaders(this.fetchAllLastResHeaders, headers); mergeHeaders(this.fetchAllLastResHeaders, headers);
if (result !== undefined) { if (result !== undefined) {
if (this.nonStreamingOrderBy && if (this.nonStreamingOrderBy && typeof result === "object" && Object.keys(result).length === 0) {
typeof result === "object" &&
Object.keys(result).length === 0) {
// ignore empty results from NonStreamingOrderBy Endpoint components. // ignore empty results from NonStreamingOrderBy Endpoint components.
} } else this.fetchAllTempResources.push(result);
else
this.fetchAllTempResources.push(result);
} }
} }
return new FeedResponse(this.fetchAllTempResources, this.fetchAllLastResHeaders, this.queryExecutionContext.hasMoreResults(), getEmptyCosmosDiagnostics()); return new FeedResponse(
this.fetchAllTempResources,
this.fetchAllLastResHeaders,
this.queryExecutionContext.hasMoreResults(),
getEmptyCosmosDiagnostics(),
);
} }
async createPipelinedExecutionContext() { async createPipelinedExecutionContext() {
const queryPlanResponse = await this.queryPlanPromise; const queryPlanResponse = await this.queryPlanPromise;
@@ -229,12 +253,25 @@ export class QueryIterator {
/*if (queryInfo.aggregates.length > 0 && queryInfo.hasSelectValue === false) { /*if (queryInfo.aggregates.length > 0 && queryInfo.hasSelectValue === false) {
throw new Error("Aggregate queries must use the VALUE keyword"); throw new Error("Aggregate queries must use the VALUE keyword");
} */ } */
this.queryExecutionContext = new PipelinedQueryExecutionContext(this.clientContext, this.resourceLink, this.query, this.options, queryPlan); this.queryExecutionContext = new PipelinedQueryExecutionContext(
this.clientContext,
this.resourceLink,
this.query,
this.options,
queryPlan,
);
} }
async fetchQueryPlan(diagnosticNode) { async fetchQueryPlan(diagnosticNode) {
if (!this.queryPlanPromise && this.resourceType === ResourceType.item) { if (!this.queryPlanPromise && this.resourceType === ResourceType.item) {
return this.clientContext return this.clientContext
.getQueryPlan(getPathFromLink(this.resourceLink) + "/docs", ResourceType.item, this.resourceLink, this.query, this.options, diagnosticNode) .getQueryPlan(
getPathFromLink(this.resourceLink) + "/docs",
ResourceType.item,
this.resourceLink,
this.query,
this.options,
diagnosticNode,
)
.catch((error) => error); // Without this catch, node reports an unhandled rejection. So we stash the promise as resolved even if it errored. .catch((error) => error); // Without this catch, node reports an unhandled rejection. So we stash the promise as resolved even if it errored.
} }
return this.queryPlanPromise; return this.queryPlanPromise;
@@ -242,10 +279,11 @@ export class QueryIterator {
needsQueryPlan(error) { needsQueryPlan(error) {
var _a; var _a;
let needsQueryPlanValue = false; let needsQueryPlanValue = false;
if (((_a = error.body) === null || _a === void 0 ? void 0 : _a.additionalErrorInfo) || if (
error.message.includes("Cross partition query only supports")) { ((_a = error.body) === null || _a === void 0 ? void 0 : _a.additionalErrorInfo) ||
needsQueryPlanValue = error.message.includes("Cross partition query only supports")
error.code === StatusCodes.BadRequest && this.resourceType === ResourceType.item; ) {
needsQueryPlanValue = error.code === StatusCodes.BadRequest && this.resourceType === ResourceType.item;
} }
return needsQueryPlanValue; return needsQueryPlanValue;
} }
@@ -270,8 +308,7 @@ export class QueryIterator {
error.code = 503; error.code = 503;
error.originalError = err; error.originalError = err;
throw error; throw error;
} } else {
else {
throw err; throw err;
} }
} }
+51 -5
View File
@@ -209,6 +209,57 @@
"extraneous": true, "extraneous": true,
"license": "ISC" "license": "ISC"
}, },
"local_dependencies/@azure/cosmos": {
"version": "4.0.1-beta.3",
"license": "MIT",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-auth": "^1.3.0",
"@azure/core-rest-pipeline": "^1.2.0",
"@azure/core-tracing": "^1.0.0",
"debug": "^4.1.1",
"fast-json-stable-stringify": "^2.1.0",
"jsbi": "^3.1.3",
"node-abort-controller": "^3.0.0",
"priorityqueuejs": "^2.0.0",
"semaphore": "^1.0.5",
"tslib": "^2.2.0",
"universal-user-agent": "^6.0.0",
"uuid": "^8.3.0"
},
"engines": {
"node": ">=18.0.0"
}
},
"local_dependencies/@azure/cosmos/node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"local_dependencies/cosmos": {
"name": "@azure/cosmos",
"version": "4.0.1-beta.3",
"extraneous": true,
"license": "MIT",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-auth": "^1.3.0",
"@azure/core-rest-pipeline": "^1.2.0",
"@azure/core-tracing": "^1.0.0",
"debug": "^4.1.1",
"fast-json-stable-stringify": "^2.1.0",
"jsbi": "^3.1.3",
"node-abort-controller": "^3.0.0",
"priorityqueuejs": "^2.0.0",
"semaphore": "^1.0.5",
"tslib": "^2.2.0",
"universal-user-agent": "^6.0.0",
"uuid": "^8.3.0"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@aashutoshrathi/word-wrap": { "node_modules/@aashutoshrathi/word-wrap": {
"version": "1.2.6", "version": "1.2.6",
"license": "MIT", "license": "MIT",
@@ -429,11 +480,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/@azure/cosmos/node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/@azure/identity": { "node_modules/@azure/identity": {
"version": "1.5.2", "version": "1.5.2",
"license": "MIT", "license": "MIT",
+1 -1
View File
@@ -131,7 +131,7 @@ export const CassandraProxyOutboundIPs: { [key: string]: string[] } = {
[CassandraProxyEndpoints.Mooncake]: ["40.73.99.146", "143.64.62.47"], [CassandraProxyEndpoints.Mooncake]: ["40.73.99.146", "143.64.62.47"],
}; };
export const allowedEmulatorEndpoints: ReadonlyArray<string> = ["https://localhost:8081","http://localhost:8081"]; export const allowedEmulatorEndpoints: ReadonlyArray<string> = ["https://localhost:8081", "http://localhost:8081"];
export const allowedMongoBackendEndpoints: ReadonlyArray<string> = ["https://localhost:1234"]; export const allowedMongoBackendEndpoints: ReadonlyArray<string> = ["https://localhost:1234"];