jinaga-server 2.3.2 → 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authentication/authentication-device.d.ts +2 -1
- package/dist/authentication/authentication-device.js +12 -3
- package/dist/authentication/authentication-device.js.map +1 -1
- package/dist/authorization/authorization-keystore.d.ts +1 -1
- package/dist/authorization/authorization-keystore.js +1 -4
- package/dist/authorization/authorization-keystore.js.map +1 -1
- package/dist/http/router.js +13 -1
- package/dist/http/router.js.map +1 -1
- package/dist/postgres/postgres-store.d.ts +2 -2
- package/dist/postgres/postgres-store.js +17 -2
- package/dist/postgres/postgres-store.js.map +1 -1
- package/dist/postgres/specification-result-sql.d.ts +23 -4
- package/dist/postgres/specification-result-sql.js +104 -33
- package/dist/postgres/specification-result-sql.js.map +1 -1
- package/package.json +2 -2
- package/src/authentication/authentication-device.ts +11 -3
- package/src/authorization/authorization-keystore.ts +2 -3
- package/src/http/router.ts +18 -1
- package/src/postgres/postgres-store.ts +26 -4
- package/src/postgres/specification-result-sql.ts +150 -38
- package/test/postgres/postgresReadSpec.ts +13 -4
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComponentProjection,
|
|
3
3
|
FactProjection,
|
|
4
|
+
FactRecord,
|
|
4
5
|
FactReference,
|
|
5
6
|
FieldProjection,
|
|
6
7
|
HashProjection,
|
|
8
|
+
hydrateFromTree,
|
|
7
9
|
Label,
|
|
8
10
|
Match,
|
|
9
11
|
PathCondition,
|
|
12
|
+
PredecessorCollection,
|
|
13
|
+
ProjectedResult,
|
|
10
14
|
Projection,
|
|
15
|
+
ReferencesByName,
|
|
11
16
|
SingularProjection,
|
|
12
17
|
Specification,
|
|
13
18
|
SpecificationProjection
|
|
@@ -18,6 +23,7 @@ import { ensureGetFactTypeId, FactTypeMap, getFactTypeId, getRoleId, RoleMap } f
|
|
|
18
23
|
interface SpecificationLabel {
|
|
19
24
|
name: string;
|
|
20
25
|
index: number;
|
|
26
|
+
type: string;
|
|
21
27
|
}
|
|
22
28
|
interface FactDescription {
|
|
23
29
|
type: string;
|
|
@@ -43,6 +49,7 @@ interface SpecificationSqlQuery {
|
|
|
43
49
|
};
|
|
44
50
|
interface InputDescription {
|
|
45
51
|
label: string;
|
|
52
|
+
type: string;
|
|
46
53
|
factIndex: number;
|
|
47
54
|
factTypeParameter: number;
|
|
48
55
|
factHashParameter: number;
|
|
@@ -100,6 +107,7 @@ class QueryDescription {
|
|
|
100
107
|
]
|
|
101
108
|
const input: InputDescription = {
|
|
102
109
|
label: label.name,
|
|
110
|
+
type: label.type,
|
|
103
111
|
factIndex,
|
|
104
112
|
factTypeParameter,
|
|
105
113
|
factHashParameter
|
|
@@ -218,8 +226,9 @@ class QueryDescription {
|
|
|
218
226
|
}
|
|
219
227
|
|
|
220
228
|
generateResultSqlQuery(schema: string): SpecificationSqlQuery {
|
|
221
|
-
const
|
|
222
|
-
|
|
229
|
+
const allLabels = [ ...this.inputs, ...this.outputs ];
|
|
230
|
+
const columns = allLabels
|
|
231
|
+
.map(label => `f${label.factIndex}.hash as hash${label.factIndex}, f${label.factIndex}.fact_id as id${label.factIndex}, f${label.factIndex}.data as data${label.factIndex}`)
|
|
223
232
|
.join(", ");
|
|
224
233
|
const firstEdge = this.edges[0];
|
|
225
234
|
const predecessorFact = this.inputs.find(i => i.factIndex === firstEdge.predecessorFactIndex);
|
|
@@ -240,10 +249,10 @@ class QueryDescription {
|
|
|
240
249
|
return {
|
|
241
250
|
sql,
|
|
242
251
|
parameters: this.parameters,
|
|
243
|
-
labels:
|
|
244
|
-
name:
|
|
245
|
-
type:
|
|
246
|
-
index:
|
|
252
|
+
labels: allLabels.map(label => ({
|
|
253
|
+
name: label.label,
|
|
254
|
+
type: label.type,
|
|
255
|
+
index: label.factIndex
|
|
247
256
|
})),
|
|
248
257
|
bookmark: "[]"
|
|
249
258
|
};
|
|
@@ -420,6 +429,7 @@ interface ResultDescription {
|
|
|
420
429
|
queryDescription: QueryDescription;
|
|
421
430
|
resultProjection: Projection;
|
|
422
431
|
childResultDescriptions: NamedResultDescription[];
|
|
432
|
+
givenTuple: ReferencesByName;
|
|
423
433
|
}
|
|
424
434
|
|
|
425
435
|
interface NamedResultDescription extends ResultDescription {
|
|
@@ -428,12 +438,13 @@ interface NamedResultDescription extends ResultDescription {
|
|
|
428
438
|
|
|
429
439
|
interface IdentifiedResults {
|
|
430
440
|
factIds: number[];
|
|
441
|
+
tuple: ReferencesByName;
|
|
431
442
|
result: any;
|
|
432
443
|
}
|
|
433
444
|
|
|
434
445
|
interface ChildResults {
|
|
435
446
|
parentFactIds: number[];
|
|
436
|
-
results:
|
|
447
|
+
results: ProjectedResult[];
|
|
437
448
|
}
|
|
438
449
|
|
|
439
450
|
export interface SqlQueryTree {
|
|
@@ -445,8 +456,23 @@ interface NamedSqlQueryTree extends SqlQueryTree {
|
|
|
445
456
|
name: string;
|
|
446
457
|
}
|
|
447
458
|
|
|
459
|
+
export interface ResultSetData {
|
|
460
|
+
fields: { [field: string]: any };
|
|
461
|
+
predecessors: PredecessorCollection;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface ResultSetFact {
|
|
465
|
+
hash: string;
|
|
466
|
+
factId: number;
|
|
467
|
+
data: ResultSetData;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export interface ResultSetRow {
|
|
471
|
+
[factIndex: number]: ResultSetFact;
|
|
472
|
+
}
|
|
473
|
+
|
|
448
474
|
export interface ResultSetTree {
|
|
449
|
-
resultSet:
|
|
475
|
+
resultSet: ResultSetRow[];
|
|
450
476
|
childResultSets: NamedResultSetTree[];
|
|
451
477
|
}
|
|
452
478
|
|
|
@@ -459,6 +485,7 @@ export class ResultComposer {
|
|
|
459
485
|
private readonly sqlQuery: SpecificationSqlQuery,
|
|
460
486
|
private readonly resultProjection: Projection,
|
|
461
487
|
private readonly parentFactIdLength: number,
|
|
488
|
+
private readonly givenTuple: ReferencesByName,
|
|
462
489
|
private readonly childResultComposers: NamedResultComposer[]
|
|
463
490
|
) { }
|
|
464
491
|
|
|
@@ -476,10 +503,56 @@ export class ResultComposer {
|
|
|
476
503
|
};
|
|
477
504
|
}
|
|
478
505
|
|
|
479
|
-
public
|
|
506
|
+
public findFactReferences(
|
|
480
507
|
resultSets: ResultSetTree
|
|
481
|
-
):
|
|
482
|
-
|
|
508
|
+
): FactReference[] {
|
|
509
|
+
let factReferences: FactReference[] = [];
|
|
510
|
+
|
|
511
|
+
// Add the fact references for selected facts.
|
|
512
|
+
const projection = this.resultProjection;
|
|
513
|
+
if (projection.type === 'fact') {
|
|
514
|
+
const projectionFactReferences = this.factReferencesForProjection(projection, resultSets);
|
|
515
|
+
factReferences = factReferences.concat(projectionFactReferences);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Add the fact references for composites.
|
|
519
|
+
if (projection.type === 'composite') {
|
|
520
|
+
for (const component of projection.components) {
|
|
521
|
+
if (component.type === 'fact') {
|
|
522
|
+
const projectionFactReferences = this.factReferencesForProjection(component, resultSets);
|
|
523
|
+
factReferences = factReferences.concat(projectionFactReferences);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Recursively add the fact references for child result sets.
|
|
529
|
+
for (const childResultSet of resultSets.childResultSets) {
|
|
530
|
+
const childResultComposer = this.childResultComposers.find(c =>
|
|
531
|
+
c.name === childResultSet.name);
|
|
532
|
+
if (childResultComposer) {
|
|
533
|
+
const childFactReferences = childResultComposer.resultComposer
|
|
534
|
+
.findFactReferences(childResultSet);
|
|
535
|
+
factReferences = factReferences.concat(childFactReferences);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return factReferences;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
private factReferencesForProjection(projection: FactProjection, resultSets: ResultSetTree) {
|
|
543
|
+
const label = this.getLabel(projection.label);
|
|
544
|
+
const factReferences = resultSets.resultSet.map(row => ({
|
|
545
|
+
type: label.type,
|
|
546
|
+
hash: row[label.index].hash
|
|
547
|
+
}));
|
|
548
|
+
return factReferences;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
public compose(
|
|
552
|
+
resultSets: ResultSetTree,
|
|
553
|
+
factRecords: FactRecord[]
|
|
554
|
+
): ProjectedResult[] {
|
|
555
|
+
const childResults = this.composeInternal(resultSets, factRecords);
|
|
483
556
|
if (childResults.length === 0) {
|
|
484
557
|
return [];
|
|
485
558
|
}
|
|
@@ -489,7 +562,8 @@ export class ResultComposer {
|
|
|
489
562
|
}
|
|
490
563
|
|
|
491
564
|
private composeInternal(
|
|
492
|
-
resultSets: ResultSetTree
|
|
565
|
+
resultSets: ResultSetTree,
|
|
566
|
+
factRecords: FactRecord[]
|
|
493
567
|
): ChildResults[] {
|
|
494
568
|
const rows = resultSets.resultSet;
|
|
495
569
|
if (rows.length === 0) {
|
|
@@ -499,7 +573,8 @@ export class ResultComposer {
|
|
|
499
573
|
// Project all rows and their identifiers
|
|
500
574
|
const identifiedResults: IdentifiedResults[] = rows.map(row => ({
|
|
501
575
|
factIds: this.identifierOf(row),
|
|
502
|
-
|
|
576
|
+
tuple: this.tupleOf(row),
|
|
577
|
+
result: this.projectionOf(row, factRecords)
|
|
503
578
|
}));
|
|
504
579
|
|
|
505
580
|
// Compose child results
|
|
@@ -510,7 +585,7 @@ export class ResultComposer {
|
|
|
510
585
|
const availableNames = resultSets.childResultSets.map(childResultSet => childResultSet.name);
|
|
511
586
|
throw new Error(`Child result set ${childResultComposer.name} not found in (${availableNames.join(", ")})`);
|
|
512
587
|
}
|
|
513
|
-
const composedResults = childResultComposer.resultComposer.composeInternal(childResultSet);
|
|
588
|
+
const composedResults = childResultComposer.resultComposer.composeInternal(childResultSet, factRecords);
|
|
514
589
|
|
|
515
590
|
// Add the child results
|
|
516
591
|
let index = 0;
|
|
@@ -530,11 +605,17 @@ export class ResultComposer {
|
|
|
530
605
|
// Group the results by their parent identifiers
|
|
531
606
|
const childResults: ChildResults[] = [];
|
|
532
607
|
let parentFactIds: number[] = identifiedResults[0].factIds.slice(0, this.parentFactIdLength);
|
|
533
|
-
let results:
|
|
608
|
+
let results: ProjectedResult[] = [{
|
|
609
|
+
tuple: identifiedResults[0].tuple,
|
|
610
|
+
result: identifiedResults[0].result
|
|
611
|
+
}];
|
|
534
612
|
for (const identifiedResult of identifiedResults.slice(1)) {
|
|
535
613
|
const nextParentFactIds = identifiedResult.factIds.slice(0, this.parentFactIdLength);
|
|
536
614
|
if (idsEqual(nextParentFactIds, parentFactIds)) {
|
|
537
|
-
results.push(
|
|
615
|
+
results.push({
|
|
616
|
+
tuple: identifiedResult.tuple,
|
|
617
|
+
result: identifiedResult.result
|
|
618
|
+
});
|
|
538
619
|
}
|
|
539
620
|
else {
|
|
540
621
|
childResults.push({
|
|
@@ -542,7 +623,10 @@ export class ResultComposer {
|
|
|
542
623
|
results
|
|
543
624
|
});
|
|
544
625
|
parentFactIds = nextParentFactIds;
|
|
545
|
-
results = [
|
|
626
|
+
results = [{
|
|
627
|
+
tuple: identifiedResult.tuple,
|
|
628
|
+
result: identifiedResult.result
|
|
629
|
+
}];
|
|
546
630
|
}
|
|
547
631
|
}
|
|
548
632
|
childResults.push({
|
|
@@ -552,11 +636,22 @@ export class ResultComposer {
|
|
|
552
636
|
return childResults;
|
|
553
637
|
}
|
|
554
638
|
|
|
555
|
-
private identifierOf(row:
|
|
556
|
-
return this.sqlQuery.labels.map(label => row[
|
|
639
|
+
private identifierOf(row: ResultSetRow): number[] {
|
|
640
|
+
return this.sqlQuery.labels.map(label => row[label.index].factId);
|
|
557
641
|
}
|
|
558
642
|
|
|
559
|
-
private
|
|
643
|
+
private tupleOf(row: ResultSetRow): ReferencesByName {
|
|
644
|
+
const tuple = this.sqlQuery.labels.reduce((acc, label) => ({
|
|
645
|
+
...acc,
|
|
646
|
+
[label.name]: {
|
|
647
|
+
type: label.type,
|
|
648
|
+
hash: row[label.index].hash,
|
|
649
|
+
}
|
|
650
|
+
}), this.givenTuple);
|
|
651
|
+
return tuple;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
private projectionOf(row: ResultSetRow, factRecords: FactRecord[]): any {
|
|
560
655
|
if (this.resultProjection.type === "field") {
|
|
561
656
|
return this.fieldValue(this.resultProjection, row);
|
|
562
657
|
}
|
|
@@ -568,13 +663,13 @@ export class ResultComposer {
|
|
|
568
663
|
.slice(this.parentFactIdLength)
|
|
569
664
|
.reduce((acc, label) => ({
|
|
570
665
|
...acc,
|
|
571
|
-
[label.name]: row[
|
|
666
|
+
[label.name]: row[label.index].data.fields
|
|
572
667
|
}), {})
|
|
573
668
|
}
|
|
574
669
|
else {
|
|
575
670
|
return this.resultProjection.components.reduce((acc, component) => ({
|
|
576
671
|
...acc,
|
|
577
|
-
[component.name]: this.elementValue(component, row)
|
|
672
|
+
[component.name]: this.elementValue(component, row, factRecords)
|
|
578
673
|
}), {});
|
|
579
674
|
}
|
|
580
675
|
}
|
|
@@ -582,7 +677,7 @@ export class ResultComposer {
|
|
|
582
677
|
return this.hashValue(this.resultProjection, row);
|
|
583
678
|
}
|
|
584
679
|
else if (this.resultProjection.type === "fact") {
|
|
585
|
-
return this.factValue(this.resultProjection, row);
|
|
680
|
+
return this.factValue(this.resultProjection, row, factRecords);
|
|
586
681
|
}
|
|
587
682
|
else {
|
|
588
683
|
const _exhaustiveCheck: never = this.resultProjection;
|
|
@@ -590,18 +685,23 @@ export class ResultComposer {
|
|
|
590
685
|
}
|
|
591
686
|
}
|
|
592
687
|
|
|
593
|
-
private elementValue(projection: ComponentProjection, row:
|
|
688
|
+
private elementValue(projection: ComponentProjection, row: ResultSetRow, factRecords: FactRecord[]): any {
|
|
594
689
|
if (projection.type === "field") {
|
|
595
690
|
const label = this.getLabel(projection.label);
|
|
596
|
-
return row[
|
|
691
|
+
return row[label.index].data.fields[projection.field];
|
|
597
692
|
}
|
|
598
693
|
else if (projection.type === "hash") {
|
|
599
694
|
const label = this.getLabel(projection.label);
|
|
600
|
-
return row[
|
|
695
|
+
return row[label.index].hash;
|
|
601
696
|
}
|
|
602
697
|
else if (projection.type === "fact") {
|
|
603
698
|
const label = this.getLabel(projection.label);
|
|
604
|
-
|
|
699
|
+
const factReference = {
|
|
700
|
+
type: label.type,
|
|
701
|
+
hash: row[label.index].hash,
|
|
702
|
+
};
|
|
703
|
+
const [fact] = hydrateFromTree([factReference], factRecords);
|
|
704
|
+
return fact;
|
|
605
705
|
}
|
|
606
706
|
else if (projection.type === "specification") {
|
|
607
707
|
// This should have already been taken care of
|
|
@@ -613,19 +713,24 @@ export class ResultComposer {
|
|
|
613
713
|
}
|
|
614
714
|
}
|
|
615
715
|
|
|
616
|
-
private fieldValue(projection: FieldProjection, row:
|
|
716
|
+
private fieldValue(projection: FieldProjection, row: ResultSetRow): any {
|
|
617
717
|
const label = this.getLabel(projection.label);
|
|
618
|
-
return row[
|
|
718
|
+
return row[label.index].data.fields[projection.field];
|
|
619
719
|
}
|
|
620
720
|
|
|
621
|
-
private hashValue(projection: HashProjection, row:
|
|
721
|
+
private hashValue(projection: HashProjection, row: ResultSetRow): any {
|
|
622
722
|
const label = this.getLabel(projection.label);
|
|
623
|
-
return row[
|
|
723
|
+
return row[label.index].hash;
|
|
624
724
|
}
|
|
625
725
|
|
|
626
|
-
private factValue(projection: FactProjection, row:
|
|
726
|
+
private factValue(projection: FactProjection, row: ResultSetRow, factRecords: FactRecord[]): any {
|
|
627
727
|
const label = this.getLabel(projection.label);
|
|
628
|
-
|
|
728
|
+
const factReference: FactReference = {
|
|
729
|
+
type: label.type,
|
|
730
|
+
hash: row[label.index].hash
|
|
731
|
+
};
|
|
732
|
+
const [fact] = hydrateFromTree([factReference], factRecords);
|
|
733
|
+
return fact;
|
|
629
734
|
}
|
|
630
735
|
|
|
631
736
|
private getLabel(name: string) {
|
|
@@ -669,6 +774,10 @@ class ResultDescriptionBuilder {
|
|
|
669
774
|
}
|
|
670
775
|
|
|
671
776
|
private createResultDescription(queryDescription: QueryDescription, given: Label[], start: FactReference[], matches: Match[], projection: Projection, knownFacts: FactByLabel, path: number[]): ResultDescription {
|
|
777
|
+
const givenTuple = given.reduce((acc, label, index) => ({
|
|
778
|
+
...acc,
|
|
779
|
+
[label.name]: start[index]
|
|
780
|
+
}), {} as ReferencesByName);
|
|
672
781
|
({ queryDescription, knownFacts } = this.addEdges(queryDescription, given, start, knownFacts, path, matches));
|
|
673
782
|
if (!queryDescription.isSatisfiable()) {
|
|
674
783
|
// Abort the branch if the query is not satisfiable
|
|
@@ -678,7 +787,8 @@ class ResultDescriptionBuilder {
|
|
|
678
787
|
type: "composite",
|
|
679
788
|
components: []
|
|
680
789
|
},
|
|
681
|
-
childResultDescriptions: []
|
|
790
|
+
childResultDescriptions: [],
|
|
791
|
+
givenTuple
|
|
682
792
|
}
|
|
683
793
|
}
|
|
684
794
|
const childResultDescriptions: NamedResultDescription[] = [];
|
|
@@ -700,14 +810,16 @@ class ResultDescriptionBuilder {
|
|
|
700
810
|
type: "composite",
|
|
701
811
|
components: singularProjections
|
|
702
812
|
},
|
|
703
|
-
childResultDescriptions
|
|
813
|
+
childResultDescriptions,
|
|
814
|
+
givenTuple
|
|
704
815
|
};
|
|
705
816
|
}
|
|
706
817
|
else {
|
|
707
818
|
return {
|
|
708
819
|
queryDescription,
|
|
709
820
|
resultProjection: projection,
|
|
710
|
-
childResultDescriptions: []
|
|
821
|
+
childResultDescriptions: [],
|
|
822
|
+
givenTuple
|
|
711
823
|
}
|
|
712
824
|
}
|
|
713
825
|
}
|
|
@@ -875,7 +987,7 @@ export function resultSqlFromSpecification(start: FactReference[], specification
|
|
|
875
987
|
if (!description.queryDescription.isSatisfiable()) {
|
|
876
988
|
return null;
|
|
877
989
|
}
|
|
878
|
-
return createResultComposer(description,
|
|
990
|
+
return createResultComposer(description, start.length, schema);
|
|
879
991
|
}
|
|
880
992
|
|
|
881
993
|
function createResultComposer(description: ResultDescription, parentFactIdLength: number, schema: string): ResultComposer {
|
|
@@ -887,5 +999,5 @@ function createResultComposer(description: ResultDescription, parentFactIdLength
|
|
|
887
999
|
name: child.name,
|
|
888
1000
|
resultComposer: createResultComposer(child, description.queryDescription.outputLength(), schema)
|
|
889
1001
|
}));
|
|
890
|
-
return new ResultComposer(sqlQuery, resultProjection, parentFactIdLength, childResultComposers);
|
|
1002
|
+
return new ResultComposer(sqlQuery, resultProjection, parentFactIdLength, description.givenTuple, childResultComposers);
|
|
891
1003
|
}
|
|
@@ -74,7 +74,9 @@ describe("Postgres read", () => {
|
|
|
74
74
|
|
|
75
75
|
const sql = composer.getSqlQueries().sqlQuery.sql;
|
|
76
76
|
expect(sql).toEqual(
|
|
77
|
-
`SELECT
|
|
77
|
+
`SELECT ` +
|
|
78
|
+
`f1.hash as hash1, f1.fact_id as id1, f1.data as data1, ` +
|
|
79
|
+
`f2.hash as hash2, f2.fact_id as id2, f2.data as data2 ` +
|
|
78
80
|
`FROM public.fact f1 ` +
|
|
79
81
|
`JOIN public.edge e1 ` +
|
|
80
82
|
`ON e1.predecessor_fact_id = f1.fact_id ` +
|
|
@@ -103,7 +105,9 @@ describe("Postgres read", () => {
|
|
|
103
105
|
const tree = composer.getSqlQueries();
|
|
104
106
|
const sql = tree.sqlQuery.sql;
|
|
105
107
|
expect(sql).toEqual(
|
|
106
|
-
`SELECT
|
|
108
|
+
`SELECT ` +
|
|
109
|
+
`f1.hash as hash1, f1.fact_id as id1, f1.data as data1, ` +
|
|
110
|
+
`f3.hash as hash3, f3.fact_id as id3, f3.data as data3 ` +
|
|
107
111
|
`FROM public.fact f1 ` +
|
|
108
112
|
`JOIN public.edge e1 ` +
|
|
109
113
|
`ON e1.predecessor_fact_id = f1.fact_id ` +
|
|
@@ -152,7 +156,9 @@ describe("Postgres read", () => {
|
|
|
152
156
|
const tree = composer.getSqlQueries();
|
|
153
157
|
const sql = tree.sqlQuery.sql;
|
|
154
158
|
expect(sql).toEqual(
|
|
155
|
-
`SELECT
|
|
159
|
+
`SELECT ` +
|
|
160
|
+
`f1.hash as hash1, f1.fact_id as id1, f1.data as data1, ` +
|
|
161
|
+
`f3.hash as hash3, f3.fact_id as id3, f3.data as data3 ` +
|
|
156
162
|
`FROM public.fact f1 ` +
|
|
157
163
|
`JOIN public.edge e1 ` +
|
|
158
164
|
`ON e1.predecessor_fact_id = f1.fact_id ` +
|
|
@@ -206,7 +212,9 @@ describe("Postgres read", () => {
|
|
|
206
212
|
const tree = composer.getSqlQueries();
|
|
207
213
|
const sql = tree.sqlQuery.sql;
|
|
208
214
|
expect(sql).toEqual(
|
|
209
|
-
`SELECT
|
|
215
|
+
`SELECT ` +
|
|
216
|
+
`f1.hash as hash1, f1.fact_id as id1, f1.data as data1, ` +
|
|
217
|
+
`f2.hash as hash2, f2.fact_id as id2, f2.data as data2 ` +
|
|
210
218
|
`FROM public.fact f1 ` +
|
|
211
219
|
`JOIN public.edge e1 ` +
|
|
212
220
|
`ON e1.predecessor_fact_id = f1.fact_id ` +
|
|
@@ -285,6 +293,7 @@ describe("Postgres read", () => {
|
|
|
285
293
|
const queries = composer.getSqlQueries();
|
|
286
294
|
expect(queries.sqlQuery.sql).toEqual(
|
|
287
295
|
`SELECT ` +
|
|
296
|
+
`f1.hash as hash1, f1.fact_id as id1, f1.data as data1, ` +
|
|
288
297
|
`f3.hash as hash3, f3.fact_id as id3, f3.data as data3, ` +
|
|
289
298
|
`f9.hash as hash9, f9.fact_id as id9, f9.data as data9 ` +
|
|
290
299
|
`FROM public.fact f1 ` +
|