Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Blob:
Table:

- Fixed "Unexpected EOF" error when batch InsertReplace entities with Go SDK (issue #2519)
- Fixed default table HealthCheck fails with 400 bad request (issue #2450, #1573)

## 2024.10 Version 3.33.0

Expand Down
12 changes: 10 additions & 2 deletions src/table/persistence/LokiTableStoreQueryGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ export default class LokiTableStoreQueryGenerator {
public static generateQueryTableWhereFunction(
query: string | undefined
): (entity: Table) => boolean {
if (query === undefined) {
if (query === undefined || query === "" || query === "true") {
return () => true;
}

if (query === "false") {
return () => false;
}

const queryTree = parseQuery(query);
validateQueryTree(queryTree);
return (entity) => executeQuery(entity, queryTree);
Expand Down Expand Up @@ -80,10 +84,14 @@ export default class LokiTableStoreQueryGenerator {
private static generateQueryEntityWhereFunction(
query: string | undefined
): (entity: Entity) => boolean {
if (query === undefined || query === "") {
if (query === undefined || query === "" || query === "true") {
return () => true;
}

if (query === "false") {
return () => false;
}

const queryTree = parseQuery(query);
validateQueryTree(queryTree);
return (entity) => executeQuery(entity, queryTree);
Expand Down
143 changes: 142 additions & 1 deletion tests/table/apis/table.entity.issues.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import {
GetTableEntityResponse,
odata,
TableEntity,
TableEntityResult
TableEntityResult,
TableItem
} from "@azure/data-tables";
import { configLogger } from "../../../src/common/Logger";
import StorageError from "../../../src/table/errors/StorageError";
import TableServer from "../../../src/table/TableServer";
import { getUniqueName } from "../../testutils";
import {
createAzureDataTablesClient,
createAzureDataTableServiceClient,
createTableServerForTestHttps,
createUniquePartitionKey
} from "../utils/table.entity.test.utils";
Expand Down Expand Up @@ -454,5 +456,144 @@ describe("table Entity APIs test : Issues", () => {
assert.strictEqual(storageError.statusCode, "InvalidInput");
assert.strictEqual(storageError.storageErrorCode, 400);
});

await tableClient.deleteTable();
});

//from issue #2450
it("should parce a simple query entity @loki", async () => {
const partitionKeyForQueryTest1 = createUniquePartitionKey("1_");
const totalItems = 2;
const tableClient = createAzureDataTablesClient(
testLocalAzuriteInstance,
tableName
);
await tableClient.createTable();

// first partition
// creates entities individually
for (let i = 0; i < totalItems; i++) {
const result = await tableClient.createEntity({
partitionKey: partitionKeyForQueryTest1,
rowKey: `${i}`,
number: i
});
assert.notStrictEqual(result.etag, undefined);
}

const maxPageSize = 5; // this should work with a page size of 1000, but fails during response serialization on my machine
let testsCompleted = 0;
// take note of the different whitespacing and query formatting:
const queriesAndExpectedResult = [
{
queryOptions: {
filter: ``
},
expectedResult: 2
},
{
queryOptions: {
filter: `false`
},
expectedResult: 0
},
{
queryOptions: {
filter: `true`
},
expectedResult: 2
}
];

for (const queryTest of queriesAndExpectedResult) {
const entities = tableClient.listEntities<TableEntity<{ number: number }>>({
queryOptions: queryTest.queryOptions,
disableTypeConversion: true
});
let all: TableEntity<{ number: number }>[] = [];
for await (const entity of entities.byPage({
maxPageSize
})) {
all = [...all, ...entity];
}
assert.strictEqual(
all.length,
queryTest.expectedResult,
`Failed with query ${queryTest.queryOptions.filter}`
);
testsCompleted++;
}
assert.strictEqual(testsCompleted, queriesAndExpectedResult.length);
await tableClient.deleteTable();

});
//from issue #2450
it("should parce a simple query tables @loki", async () => {
const tableClient = createAzureDataTableServiceClient(
testLocalAzuriteInstance
);

// not all test remove tables after running
// so we need to remove the table if it exists
const maxPageSize = 5;
const tables = tableClient.listTables();
let all: TableItem[] = [];
for await (const table of tables.byPage({
maxPageSize
})) {
all = [...all, ...table];
}

for (const table of all) {
if(table.name) {
await tableClient.deleteTable(table.name);
}
}

await tableClient.createTable(tableName);

let testsCompleted = 0;
// take note of the different whitespacing and query formatting:
const queriesAndExpectedResult = [
{
queryOptions: {
filter: ``
},
expectedResult: 1
},
{
queryOptions: {
filter: `false`
},
expectedResult: 0
},
{
queryOptions: {
filter: `true`
},
expectedResult: 1
}
];

for (const queryTest of queriesAndExpectedResult) {
const tables = tableClient.listTables({
queryOptions: queryTest.queryOptions
});
let all: TableItem[] = [];
for await (const table of tables.byPage({
maxPageSize
})) {
all = [...all, ...table];
}
assert.strictEqual(
all.length,
queryTest.expectedResult,
`Failed with query ${queryTest.queryOptions.filter}`
);
testsCompleted++;
}
assert.strictEqual(testsCompleted, queriesAndExpectedResult.length);
await tableClient.deleteTable(tableName);

});
});
36 changes: 35 additions & 1 deletion tests/table/utils/table.entity.test.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import TableServer from "../../../src/table/TableServer";
import {
AzureNamedKeyCredential,
AzureSASCredential,
TableClient
TableClient,
TableServiceClient
} from "@azure/data-tables";
import { copyFile } from "fs";
import TableTestServerFactory, { ITableTestServerFactoryParams } from "./TableTestServerFactory";
Expand Down Expand Up @@ -183,7 +184,40 @@ export function createAzureDataTablesClient(
);
}
}
/**
* creates an Azure Data Tables client for local or service tests
*
* @export
* @param {boolean} local
* @param {string} tableName
* @return {*} {TableClient}
*/
export function createAzureDataTableServiceClient(
local: boolean
): TableServiceClient {
if (local) {
const sharedKeyCredential = new AzureNamedKeyCredential(
EMULATOR_ACCOUNT_NAME,
EMULATOR_ACCOUNT_KEY
);

return new TableServiceClient(
`https://${HOST}:${PORT}/${EMULATOR_ACCOUNT_NAME}`,
sharedKeyCredential
);
} else {
// return new TableClient(
// process.env[AZURE_DATATABLES_STORAGE_STRING]! +
// process.env[AZURE_DATATABLES_SAS]!,
// tableName
// );

return new TableServiceClient(
process.env[AZURE_DATATABLES_STORAGE_STRING]!,
new AzureSASCredential(process.env[AZURE_DATATABLES_SAS]!)
);
}
}
/**
* Default behavior will overwrite target.
* This will copy the old db file with older schema on which we then
Expand Down
Loading