@@ -2,13 +2,10 @@ import {YQLType} from '../types';
22import type {
33 AnyExecuteResponse ,
44 AnyExplainResponse ,
5- AnyResponse ,
6- CommonFields ,
7- DeepExecuteResponse ,
8- DeprecatedExecuteResponsePlain ,
9- ExecuteClassicResponsePlain ,
105 ExecuteModernResponse ,
116 KeyValueRow ,
7+ ScanPlan ,
8+ ScriptPlan ,
129} from '../types/api/query' ;
1310import type { IQueryResult } from '../types/store/query' ;
1411
@@ -49,6 +46,7 @@ export const getColumnType = (type: string) => {
4946 }
5047} ;
5148
49+ /** parse response result field from ArrayRow to KeyValueRow */
5250const parseExecuteModernResponse = ( data : ExecuteModernResponse ) : IQueryResult => {
5351 const { result, columns, ...restData } = data ;
5452
@@ -57,43 +55,17 @@ const parseExecuteModernResponse = (data: ExecuteModernResponse): IQueryResult =
5755 result &&
5856 columns &&
5957 result . map ( ( row ) => {
60- return row . reduce ( ( newRow : KeyValueRow , cellData , columnIndex ) => {
58+ return row . reduce ( ( newRow , cellData , columnIndex ) => {
6159 const { name} = columns [ columnIndex ] ;
6260 newRow [ name ] = cellData ;
6361 return newRow ;
64- } , { } ) ;
62+ } , { } as KeyValueRow ) ;
6563 } ) ,
6664 columns,
6765 ...restData ,
6866 } ;
6967} ;
7068
71- const parseDeprecatedExecuteResponseValue = (
72- data ?: DeprecatedExecuteResponsePlain | ExecuteClassicResponsePlain ,
73- ) : KeyValueRow [ ] | undefined => {
74- if ( ! data ) {
75- return undefined ;
76- }
77-
78- if ( typeof data === 'string' ) {
79- try {
80- return JSON . parse ( data ) ;
81- } catch ( e ) {
82- return undefined ;
83- }
84- }
85-
86- if ( Array . isArray ( data ) ) {
87- return data ;
88- }
89-
90- // Plan is not a valid response in this case
91- return undefined ;
92- } ;
93-
94- const hasResult = ( data : AnyExecuteResponse ) : data is DeepExecuteResponse =>
95- Boolean ( data && typeof data === 'object' && 'result' in data ) ;
96-
9769const isModern = ( response : AnyExecuteResponse ) : response is ExecuteModernResponse =>
9870 Boolean (
9971 response &&
@@ -102,70 +74,64 @@ const isModern = (response: AnyExecuteResponse): response is ExecuteModernRespon
10274 Array . isArray ( ( response as ExecuteModernResponse ) . columns ) ,
10375 ) ;
10476
105- const hasCommonFields = ( data : AnyResponse ) : data is CommonFields =>
106- Boolean (
107- data && typeof data === 'object' && ( 'ast' in data || 'plan' in data || 'stats' in data ) ,
77+ type UnsupportedQueryResponseFormat =
78+ | Array < unknown >
79+ | string
80+ | null
81+ | undefined
82+ | { result : string | Record < string , unknown > } ;
83+
84+ const isUnsupportedType = (
85+ data : AnyExecuteResponse | AnyExplainResponse | UnsupportedQueryResponseFormat ,
86+ ) : data is UnsupportedQueryResponseFormat => {
87+ return Boolean (
88+ ! data ||
89+ typeof data !== 'object' ||
90+ Array . isArray ( data ) ||
91+ ( 'result' in data && ! Array . isArray ( data . result ) ) ,
10892 ) ;
93+ } ;
10994
110- // complex logic because of the variety of possible responses
111- // after all backends are updated to the latest version, it can be simplified
112- export const parseQueryAPIExecuteResponse = ( data : AnyExecuteResponse ) : IQueryResult => {
113- if ( ! data ) {
95+ export const parseQueryAPIExecuteResponse = (
96+ data : AnyExecuteResponse | UnsupportedQueryResponseFormat ,
97+ ) : IQueryResult => {
98+ if ( isUnsupportedType ( data ) ) {
11499 return { } ;
115100 }
116-
117- if ( hasResult ( data ) ) {
118- if ( isModern ( data ) ) {
119- return parseExecuteModernResponse ( data ) ;
120- }
121-
122- return {
123- ...data ,
124- result : parseDeprecatedExecuteResponseValue ( data . result ) ,
125- } ;
126- }
127-
128- if ( hasCommonFields ( data ) ) {
129- return data ;
101+ if ( isModern ( data ) ) {
102+ return parseExecuteModernResponse ( data ) ;
130103 }
131104
132- return {
133- result : parseDeprecatedExecuteResponseValue ( data ) ,
134- } ;
105+ return data ;
135106} ;
136107
137- // complex logic because of the variety of possible responses
138- // after all backends are updated to the latest version, it can be simplified
139- export const parseQueryAPIExplainResponse = ( data : AnyExplainResponse ) : IQueryResult => {
140- if ( ! data ) {
108+ export const parseQueryAPIExplainResponse = (
109+ data : AnyExplainResponse | UnsupportedQueryResponseFormat ,
110+ ) : IQueryResult => {
111+ if ( isUnsupportedType ( data ) ) {
141112 return { } ;
142113 }
143114
144- if ( 'ast' in data ) {
145- return data ;
146- }
115+ return data ;
116+ } ;
147117
148- if ( 'result' in data ) {
149- const { result , ... restData } = data ;
118+ const isExplainScriptPlan = ( plan : ScriptPlan | ScanPlan ) : plan is ScriptPlan =>
119+ Boolean ( plan && 'queries' in plan ) ;
150120
151- if ( 'ast' in data . result ) {
152- return {
153- ast : result . ast ,
154- ...restData ,
155- } ;
121+ export const parseQueryExplainPlan = ( plan : ScriptPlan | ScanPlan ) : ScanPlan => {
122+ if ( isExplainScriptPlan ( plan ) ) {
123+ if ( ! plan . queries || ! plan . queries . length ) {
124+ return { meta : plan . meta } ;
156125 }
157126
158127 return {
159- plan : data . result ,
160- ...restData ,
128+ Plan : plan . queries [ 0 ] . Plan ,
129+ tables : plan . queries [ 0 ] . tables ,
130+ meta : plan . meta ,
161131 } ;
162132 }
163133
164- if ( hasCommonFields ( data ) ) {
165- return data ;
166- }
167-
168- return { plan : data } ;
134+ return plan ;
169135} ;
170136
171137export const prepareQueryResponse = ( data ?: KeyValueRow [ ] ) => {
0 commit comments