Skip to content

Commit

Permalink
Fix double-encoding of queryValues
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie committed Feb 7, 2024
1 parent 7afbd38 commit a61741a
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 2 deletions.
3 changes: 1 addition & 2 deletions grafast/dataplan-pg/src/steps/pgSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ import { pgPageInfo } from "./pgPageInfo.js";
import type { PgSelectSinglePlanOptions } from "./pgSelectSingle.js";
import { PgSelectSingleStep } from "./pgSelectSingle.js";
import { pgValidateParsedCursor } from "./pgValidateParsedCursor.js";
import { toPg } from "./toPg.js";

export type PgSelectParsedCursorStep = LambdaStep<string, any[]>;

Expand Down Expand Up @@ -1099,7 +1098,7 @@ export class PgSelectStep<
getFragmentAndCodecFromOrder(this.alias, order, this.resource.codec);
const { nulls, direction } = order;
const sqlValue = this.placeholder(
toPg(access($parsedCursorPlan, [i + 1]), orderCodec),
access($parsedCursorPlan, [i + 1]),
orderCodec,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
page1: {
pageInfo: {
startCursor: "WyIzNjY0MzE3ZDgwIixmYWxzZSwyLDFd",
endCursor: "WyIzNjY0MzE3ZDgwIixmYWxzZSwyLDFd",
hasNextPage: true,
hasPreviousPage: false,
},
totalCount: 6,
edges: [
{
cursor: "WyIzNjY0MzE3ZDgwIixmYWxzZSwyLDFd",
node: {
extra: false,
personId1: 2,
personId2: 1,
},
},
],
},
page2: {
pageInfo: {
startCursor: "WyIzNjY0MzE3ZDgwIixmYWxzZSw0LDRd",
endCursor: "WyIzNjY0MzE3ZDgwIixmYWxzZSw0LDRd",
hasNextPage: true,
hasPreviousPage: false,
},
totalCount: 6,
edges: [
{
cursor: "WyIzNjY0MzE3ZDgwIixmYWxzZSw0LDRd",
node: {
extra: false,
personId1: 4,
personId2: 4,
},
},
],
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
%%{init: {'themeVariables': { 'fontSize': '12px'}}}%%
graph TD
classDef path fill:#eee,stroke:#000,color:#000
classDef plan fill:#fff,stroke-width:1px,color:#000
classDef itemplan fill:#fff,stroke-width:2px,color:#000
classDef unbatchedplan fill:#dff,stroke-width:1px,color:#000
classDef sideeffectplan fill:#fcc,stroke-width:2px,color:#000
classDef bucket fill:#f6f6f6,color:#000,stroke-width:2px,text-align:left


%% plan dependencies
Connection71{{"Connection[71∈0]<br />ᐸ67ᐳ"}}:::plan
Constant124{{"Constant[124∈0]<br />ᐸ1ᐳ"}}:::plan
Lambda72{{"Lambda[72∈0]<br />ᐸparseCursorᐳ"}}:::plan
PgValidateParsedCursor78["PgValidateParsedCursor[78∈0]"]:::plan
Constant124 & Lambda72 & PgValidateParsedCursor78 & PgValidateParsedCursor78 & PgValidateParsedCursor78 & PgValidateParsedCursor78 --> Connection71
Object20{{"Object[20∈0]<br />ᐸ{pgSettings,withPgClient}ᐳ"}}:::plan
Access18{{"Access[18∈0]<br />ᐸ3.pgSettingsᐳ"}}:::plan
Access19{{"Access[19∈0]<br />ᐸ3.withPgClientᐳ"}}:::plan
Access18 & Access19 --> Object20
__Value3["__Value[3∈0]<br />ᐸcontextᐳ"]:::plan
__Value3 --> Access18
__Value3 --> Access19
Connection21{{"Connection[21∈0]<br />ᐸ17ᐳ"}}:::plan
Constant124 --> Connection21
Constant126{{"Constant[126∈0]<br />ᐸ'WyIzNjY0MzE3ZDgwIixmYWxzZSwyLDFd'ᐳ"}}:::plan
Constant126 --> Lambda72
Lambda72 --> PgValidateParsedCursor78
__Value0["__Value[0∈0]"]:::plan
__Value5["__Value[5∈0]<br />ᐸrootValueᐳ"]:::plan
Constant41{{"Constant[41∈0]<br />ᐸfalseᐳ"}}:::plan
List30{{"List[30∈1]<br />ᐸ27,28,29ᐳ"}}:::plan
PgClassExpression27{{"PgClassExpression[27∈1]<br />ᐸ__compound...__.”extra”ᐳ"}}:::plan
PgClassExpression28{{"PgClassExpression[28∈1]<br />ᐸ__compound...rson_id_1”ᐳ"}}:::plan
PgClassExpression29{{"PgClassExpression[29∈1]<br />ᐸ__compound...rson_id_2”ᐳ"}}:::plan
PgClassExpression27 & PgClassExpression28 & PgClassExpression29 --> List30
List38{{"List[38∈1]<br />ᐸ35,36,37ᐳ"}}:::plan
PgClassExpression35{{"PgClassExpression[35∈1]<br />ᐸ__compound...__.”extra”ᐳ"}}:::plan
PgClassExpression36{{"PgClassExpression[36∈1]<br />ᐸ__compound...rson_id_1”ᐳ"}}:::plan
PgClassExpression37{{"PgClassExpression[37∈1]<br />ᐸ__compound...rson_id_2”ᐳ"}}:::plan
PgClassExpression35 & PgClassExpression36 & PgClassExpression37 --> List38
PgSelect23[["PgSelect[23∈1]<br />ᐸcompound_key+1ᐳ"]]:::plan
Object20 & Connection21 --> PgSelect23
PgSelect42[["PgSelect[42∈1]<br />ᐸcompound_key(aggregate)ᐳ"]]:::plan
Object20 & Connection21 --> PgSelect42
PgPageInfo22{{"PgPageInfo[22∈1]"}}:::plan
Connection21 --> PgPageInfo22
First24{{"First[24∈1]"}}:::plan
PgSelect23 --> First24
PgSelectSingle25{{"PgSelectSingle[25∈1]<br />ᐸcompound_keyᐳ"}}:::plan
First24 --> PgSelectSingle25
PgCursor26{{"PgCursor[26∈1]"}}:::plan
List30 --> PgCursor26
PgSelectSingle25 --> PgClassExpression27
PgSelectSingle25 --> PgClassExpression28
PgSelectSingle25 --> PgClassExpression29
Last32{{"Last[32∈1]"}}:::plan
PgSelect23 --> Last32
PgSelectSingle33{{"PgSelectSingle[33∈1]<br />ᐸcompound_keyᐳ"}}:::plan
Last32 --> PgSelectSingle33
PgCursor34{{"PgCursor[34∈1]"}}:::plan
List38 --> PgCursor34
PgSelectSingle33 --> PgClassExpression35
PgSelectSingle33 --> PgClassExpression36
PgSelectSingle33 --> PgClassExpression37
Access40{{"Access[40∈1]<br />ᐸ23.hasMoreᐳ"}}:::plan
PgSelect23 --> Access40
First43{{"First[43∈1]"}}:::plan
PgSelect42 --> First43
PgSelectSingle44{{"PgSelectSingle[44∈1]<br />ᐸcompound_keyᐳ"}}:::plan
First43 --> PgSelectSingle44
PgClassExpression45{{"PgClassExpression[45∈1]<br />ᐸcount(*)ᐳ"}}:::plan
PgSelectSingle44 --> PgClassExpression45
__Item47[/"__Item[47∈2]<br />ᐸ23ᐳ"\]:::itemplan
PgSelect23 ==> __Item47
PgSelectSingle48{{"PgSelectSingle[48∈2]<br />ᐸcompound_keyᐳ"}}:::plan
__Item47 --> PgSelectSingle48
List53{{"List[53∈3]<br />ᐸ50,51,52ᐳ"}}:::plan
PgClassExpression50{{"PgClassExpression[50∈3]<br />ᐸ__compound...__.”extra”ᐳ"}}:::plan
PgClassExpression51{{"PgClassExpression[51∈3]<br />ᐸ__compound...rson_id_1”ᐳ"}}:::plan
PgClassExpression52{{"PgClassExpression[52∈3]<br />ᐸ__compound...rson_id_2”ᐳ"}}:::plan
PgClassExpression50 & PgClassExpression51 & PgClassExpression52 --> List53
PgCursor49{{"PgCursor[49∈3]"}}:::plan
List53 --> PgCursor49
PgSelectSingle48 --> PgClassExpression50
PgSelectSingle48 --> PgClassExpression51
PgSelectSingle48 --> PgClassExpression52
PgSelect74[["PgSelect[74∈4]<br />ᐸcompound_key+1ᐳ"]]:::plan
Access79{{"Access[79∈4]<br />ᐸ72.1ᐳ"}}:::plan
Access80{{"Access[80∈4]<br />ᐸ72.2ᐳ"}}:::plan
Access81{{"Access[81∈4]<br />ᐸ72.3ᐳ"}}:::plan
Object20 & Connection71 & Lambda72 & Access79 & Access80 & Access81 --> PgSelect74
List85{{"List[85∈4]<br />ᐸ82,83,84ᐳ"}}:::plan
PgClassExpression82{{"PgClassExpression[82∈4]<br />ᐸ__compound...__.”extra”ᐳ"}}:::plan
PgClassExpression83{{"PgClassExpression[83∈4]<br />ᐸ__compound...rson_id_1”ᐳ"}}:::plan
PgClassExpression84{{"PgClassExpression[84∈4]<br />ᐸ__compound...rson_id_2”ᐳ"}}:::plan
PgClassExpression82 & PgClassExpression83 & PgClassExpression84 --> List85
List97{{"List[97∈4]<br />ᐸ94,95,96ᐳ"}}:::plan
PgClassExpression94{{"PgClassExpression[94∈4]<br />ᐸ__compound...__.”extra”ᐳ"}}:::plan
PgClassExpression95{{"PgClassExpression[95∈4]<br />ᐸ__compound...rson_id_1”ᐳ"}}:::plan
PgClassExpression96{{"PgClassExpression[96∈4]<br />ᐸ__compound...rson_id_2”ᐳ"}}:::plan
PgClassExpression94 & PgClassExpression95 & PgClassExpression96 --> List97
PgSelect105[["PgSelect[105∈4]<br />ᐸcompound_key(aggregate)ᐳ"]]:::plan
Object20 & Connection71 --> PgSelect105
PgPageInfo73{{"PgPageInfo[73∈4]"}}:::plan
Connection71 --> PgPageInfo73
First75{{"First[75∈4]"}}:::plan
PgSelect74 --> First75
PgSelectSingle76{{"PgSelectSingle[76∈4]<br />ᐸcompound_keyᐳ"}}:::plan
First75 --> PgSelectSingle76
PgCursor77{{"PgCursor[77∈4]"}}:::plan
List85 --> PgCursor77
Lambda72 --> Access79
Lambda72 --> Access80
Lambda72 --> Access81
PgSelectSingle76 --> PgClassExpression82
PgSelectSingle76 --> PgClassExpression83
PgSelectSingle76 --> PgClassExpression84
Last87{{"Last[87∈4]"}}:::plan
PgSelect74 --> Last87
PgSelectSingle88{{"PgSelectSingle[88∈4]<br />ᐸcompound_keyᐳ"}}:::plan
Last87 --> PgSelectSingle88
PgCursor89{{"PgCursor[89∈4]"}}:::plan
List97 --> PgCursor89
PgSelectSingle88 --> PgClassExpression94
PgSelectSingle88 --> PgClassExpression95
PgSelectSingle88 --> PgClassExpression96
Access99{{"Access[99∈4]<br />ᐸ74.hasMoreᐳ"}}:::plan
PgSelect74 --> Access99
First106{{"First[106∈4]"}}:::plan
PgSelect105 --> First106
PgSelectSingle107{{"PgSelectSingle[107∈4]<br />ᐸcompound_keyᐳ"}}:::plan
First106 --> PgSelectSingle107
PgClassExpression108{{"PgClassExpression[108∈4]<br />ᐸcount(*)ᐳ"}}:::plan
PgSelectSingle107 --> PgClassExpression108
__Item114[/"__Item[114∈5]<br />ᐸ74ᐳ"\]:::itemplan
PgSelect74 ==> __Item114
PgSelectSingle115{{"PgSelectSingle[115∈5]<br />ᐸcompound_keyᐳ"}}:::plan
__Item114 --> PgSelectSingle115
List120{{"List[120∈6]<br />ᐸ117,118,119ᐳ"}}:::plan
PgClassExpression117{{"PgClassExpression[117∈6]<br />ᐸ__compound...__.”extra”ᐳ"}}:::plan
PgClassExpression118{{"PgClassExpression[118∈6]<br />ᐸ__compound...rson_id_1”ᐳ"}}:::plan
PgClassExpression119{{"PgClassExpression[119∈6]<br />ᐸ__compound...rson_id_2”ᐳ"}}:::plan
PgClassExpression117 & PgClassExpression118 & PgClassExpression119 --> List120
PgCursor116{{"PgCursor[116∈6]"}}:::plan
List120 --> PgCursor116
PgSelectSingle115 --> PgClassExpression117
PgSelectSingle115 --> PgClassExpression118
PgSelectSingle115 --> PgClassExpression119

%% define steps

subgraph "Buckets for queries/v4/connections.boolean"
Bucket0("Bucket 0 (root)<br />1: <br />ᐳ: 18, 19, 41, 124, 126, 20, 21, 72<br />2: PgValidateParsedCursor[78]<br />ᐳ: Connection[71]"):::bucket
classDef bucket0 stroke:#696969
class Bucket0,__Value0,__Value3,__Value5,Access18,Access19,Object20,Connection21,Constant41,Connection71,Lambda72,PgValidateParsedCursor78,Constant124,Constant126 bucket0
Bucket1("Bucket 1 (nullableBoundary)<br />Deps: 21, 20, 41<br /><br />ROOT Connectionᐸ17ᐳ[21]"):::bucket
classDef bucket1 stroke:#00bfff
class Bucket1,PgPageInfo22,PgSelect23,First24,PgSelectSingle25,PgCursor26,PgClassExpression27,PgClassExpression28,PgClassExpression29,List30,Last32,PgSelectSingle33,PgCursor34,PgClassExpression35,PgClassExpression36,PgClassExpression37,List38,Access40,PgSelect42,First43,PgSelectSingle44,PgClassExpression45 bucket1
Bucket2("Bucket 2 (listItem)<br />ROOT __Item{2}ᐸ23ᐳ[47]"):::bucket
classDef bucket2 stroke:#7f007f
class Bucket2,__Item47,PgSelectSingle48 bucket2
Bucket3("Bucket 3 (nullableBoundary)<br />Deps: 48<br /><br />ROOT PgSelectSingle{2}ᐸcompound_keyᐳ[48]"):::bucket
classDef bucket3 stroke:#ffa500
class Bucket3,PgCursor49,PgClassExpression50,PgClassExpression51,PgClassExpression52,List53 bucket3
Bucket4("Bucket 4 (nullableBoundary)<br />Deps: 71, 20, 72, 41<br /><br />ROOT Connectionᐸ67ᐳ[71]<br />1: PgSelect[105]<br />ᐳ: 73, 79, 80, 81, 106, 107, 108<br />2: PgSelect[74]<br />ᐳ: 75, 76, 82, 83, 84, 85, 87, 88, 94, 95, 96, 97, 99, 77, 89"):::bucket
classDef bucket4 stroke:#0000ff
class Bucket4,PgPageInfo73,PgSelect74,First75,PgSelectSingle76,PgCursor77,Access79,Access80,Access81,PgClassExpression82,PgClassExpression83,PgClassExpression84,List85,Last87,PgSelectSingle88,PgCursor89,PgClassExpression94,PgClassExpression95,PgClassExpression96,List97,Access99,PgSelect105,First106,PgSelectSingle107,PgClassExpression108 bucket4
Bucket5("Bucket 5 (listItem)<br />ROOT __Item{5}ᐸ74ᐳ[114]"):::bucket
classDef bucket5 stroke:#7fff00
class Bucket5,__Item114,PgSelectSingle115 bucket5
Bucket6("Bucket 6 (nullableBoundary)<br />Deps: 115<br /><br />ROOT PgSelectSingle{5}ᐸcompound_keyᐳ[115]"):::bucket
classDef bucket6 stroke:#ff1493
class Bucket6,PgCursor116,PgClassExpression117,PgClassExpression118,PgClassExpression119,List120 bucket6
Bucket0 --> Bucket1 & Bucket4
Bucket1 --> Bucket2
Bucket2 --> Bucket3
Bucket4 --> Bucket5
Bucket5 --> Bucket6
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
select
__compound_key__."extra"::text as "0",
__compound_key__."person_id_1"::text as "1",
__compound_key__."person_id_2"::text as "2"
from "c"."compound_key" as __compound_key__
order by __compound_key__."extra" asc, __compound_key__."person_id_1" asc, __compound_key__."person_id_2" asc
limit 2;

select
(count(*))::text as "0"
from "c"."compound_key" as __compound_key__;

select __compound_key_result__.*
from (select 0 as idx, $1::"bool" as "id0", $2::"int4" as "id1", $3::"int4" as "id2") as __compound_key_identifiers__,
lateral (
select
__compound_key__."extra"::text as "0",
__compound_key__."person_id_1"::text as "1",
__compound_key__."person_id_2"::text as "2",
__compound_key_identifiers__.idx as "3"
from "c"."compound_key" as __compound_key__
where (
(((__compound_key__."extra" > __compound_key_identifiers__."id0") or (__compound_key__."extra" is not null and __compound_key_identifiers__."id0" is null)))
or (
__compound_key__."extra" is not distinct from __compound_key_identifiers__."id0"
and
((__compound_key__."person_id_1" > __compound_key_identifiers__."id1")
or (
__compound_key__."person_id_1" = __compound_key_identifiers__."id1"
and
(__compound_key__."person_id_2" > __compound_key_identifiers__."id2")
))
)
)
order by __compound_key__."extra" asc, __compound_key__."person_id_1" asc, __compound_key__."person_id_2" asc
limit 2
) as __compound_key_result__;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## expect(errors).toBeFalsy();
## expect(data.page1.pageInfo.endCursor).toEqual("WyIzNjY0MzE3ZDgwIixmYWxzZSwyLDFd")
#> schema: ["a", "b", "c"]
#> subscriptions: true
query {
page1: allCompoundKeys(
orderBy: [EXTRA_ASC, PERSON_ID_1_ASC, PERSON_ID_2_ASC]
first: 1
) {
...compoundKeysConnection
}
page2: allCompoundKeys(
orderBy: [EXTRA_ASC, PERSON_ID_1_ASC, PERSON_ID_2_ASC]
first: 1
after: "WyIzNjY0MzE3ZDgwIixmYWxzZSwyLDFd"
) {
...compoundKeysConnection
}
}

fragment compoundKeysConnection on CompoundKeysConnection {
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
totalCount
edges {
cursor
node {
extra
personId1
personId2
}
}
}

0 comments on commit a61741a

Please sign in to comment.