Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit87153d3

Browse files
committed
implement IS needed for schema check feature. Index doesnt support it yet
1 parent7ddf618 commit87153d3

File tree

8 files changed

+200
-18
lines changed

8 files changed

+200
-18
lines changed

‎expected/jsquery.out

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,73 @@ ERROR: bad jsquery representation
958958
LINE 1: select 'a\r = x"\\abcd"'::jsquery AS err;
959959
^
960960
DETAIL: syntax error, unexpected STRING_P, expecting $end at or near """
961+
--IS
962+
select 'as IS boolean | as is ARRAY | as is ObJect | as is Number | as is string'::jsquery;
963+
jsquery
964+
--------------------------------------------------------------------------------------------
965+
(((("as" IS BOOLEAN | "as" IS ARRAY) | "as" IS OBJECT) | "as" IS NUMBER) | "as" IS STRING)
966+
(1 row)
967+
968+
select '{"as": "xxx"}' @@ 'as IS string'::jsquery;
969+
?column?
970+
----------
971+
t
972+
(1 row)
973+
974+
select '{"as": "xxx"}' @@ 'as IS boolean | as is ARRAY | as is ObJect | as is Number'::jsquery;
975+
?column?
976+
----------
977+
f
978+
(1 row)
979+
980+
select '{"as": 5}' @@ 'as is Number'::jsquery;
981+
?column?
982+
----------
983+
t
984+
(1 row)
985+
986+
select '{"as": true}' @@ 'as is boolean'::jsquery;
987+
?column?
988+
----------
989+
t
990+
(1 row)
991+
992+
select '{"as": false}' @@ 'as is boolean'::jsquery;
993+
?column?
994+
----------
995+
t
996+
(1 row)
997+
998+
select '{"as": "false"}' @@ 'as is boolean'::jsquery;
999+
?column?
1000+
----------
1001+
f
1002+
(1 row)
1003+
1004+
select '["xxx"]' @@ '$ IS array'::jsquery;
1005+
?column?
1006+
----------
1007+
t
1008+
(1 row)
1009+
1010+
select '{"as": false}' @@ '$ IS object'::jsquery;
1011+
?column?
1012+
----------
1013+
t
1014+
(1 row)
1015+
1016+
select '"xxx"' @@ '$ IS string'::jsquery;
1017+
?column?
1018+
----------
1019+
t
1020+
(1 row)
1021+
1022+
select '"xxx"' @@ '$ IS number'::jsquery;
1023+
?column?
1024+
----------
1025+
f
1026+
(1 row)
1027+
9611028
---table and index
9621029
select count(*) from test_jsquery where (v->>'review_helpful_votes')::int4 > 0;
9631030
count

‎jsquery.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ typedef enum JsQueryItemType {
5151
jqiAnyKey='%',
5252
jqiKey='K',
5353
jqiCurrent='$',
54-
jqiIn='I'
54+
jqiIn='I',
55+
jqiIs='i'
5556
}JsQueryItemType;
5657

5758
/*
@@ -87,8 +88,6 @@ typedef struct JsQueryItem {
8788
int32*arrayPtr;
8889
}array;
8990
};
90-
91-
9291
}JsQueryItem;
9392

9493
externvoidjsqInit(JsQueryItem*v,JsQuery*js);
@@ -99,6 +98,7 @@ extern void jsqGetLeftArg(JsQueryItem *v, JsQueryItem *a);
9998
externvoidjsqGetRightArg(JsQueryItem*v,JsQueryItem*a);
10099
externNumericjsqGetNumeric(JsQueryItem*v);
101100
externbooljsqGetBool(JsQueryItem*v);
101+
externint32jsqGetIsType(JsQueryItem*v);
102102
externchar*jsqGetString(JsQueryItem*v,int32*len);
103103
externvoidjsqIterateInit(JsQueryItem*v);
104104
externbooljsqIterateArray(JsQueryItem*v,JsQueryItem*e);
@@ -122,6 +122,7 @@ struct JsQueryParseItem {
122122
}args;
123123

124124
JsQueryParseItem*arg;
125+
int8isType;/* jbv* values */
125126

126127
Numericnumeric;
127128
boolboolean;

‎jsquery_gram.y

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ makeItemUnary(int type, JsQueryParseItem* a)
152152
return v;
153153
}
154154

155+
static JsQueryParseItem*
156+
makeItemIs(int isType)
157+
{
158+
JsQueryParseItem *v =makeItemType(jqiIs);
159+
160+
v->isType = isType;
161+
162+
return v;
163+
}
164+
155165
static JsQueryParseItem*
156166
makeItemList(List *list) {
157167
JsQueryParseItem*head, *end;
@@ -183,21 +193,23 @@ makeItemList(List *list) {
183193

184194
%union {
185195
string str;
186-
Numericnumeric;
187196
List*elems;/* list of JsQueryParseItem*/
188197

189198
JsQueryParseItem*value;
190199
}
191200

192-
%token<str>NULL_PSTRING_PTRUE_PFALSE_P
193-
NUMERIC_PIN_P
201+
%token<str>IN_PIS_PNULL_PTRUE_PARRAY_P
202+
FALSE_PNUMBER_POBJECT_PTEXT_P
203+
BOOLEAN_P
204+
205+
%token<str>STRING_PNUMERIC_P
194206

195-
%type<value>resultscalar_value
196-
%type<str>key
207+
%type<value>resultscalar_value
208+
%type<str>key
197209

198-
%type<elems>pathvalue_list
210+
%type<elems>pathvalue_list
199211

200-
%type<value>path_elemright_exprexprarray
212+
%type<value>path_elemright_exprexprarray
201213

202214
%left'|'
203215
%left'&'
@@ -216,11 +228,17 @@ array:
216228
;
217229

218230
scalar_value:
219-
NULL_P{$$ = makeItemString(NULL); }
220-
|STRING_P{$$ = makeItemString(&$1); }
231+
STRING_P{$$ = makeItemString(&$1); }
221232
|IN_P{$$ = makeItemString(&$1); }
233+
|IS_P{$$ = makeItemString(&$1); }
234+
|NULL_P{$$ = makeItemString(NULL); }
222235
|TRUE_P{$$ = makeItemBool(true); }
236+
|ARRAY_P{$$ = makeItemString(&$1); }
223237
|FALSE_P{$$ = makeItemBool(false); }
238+
|NUMBER_P{$$ = makeItemString(&$1); }
239+
|OBJECT_P{$$ = makeItemString(&$1); }
240+
|TEXT_P{$$ = makeItemString(&$1); }
241+
|BOOLEAN_P{$$ = makeItemString(&$1); }
224242
|NUMERIC_P{$$ = makeItemNumeric(&$1); }
225243
;
226244

@@ -241,6 +259,11 @@ right_expr:
241259
|'@''>'array{$$ = makeItemUnary(jqiContains,$3); }
242260
|'<''@'array{$$ = makeItemUnary(jqiContained,$3); }
243261
|'&''&'array{$$ = makeItemUnary(jqiOverlap,$3); }
262+
|IS_PARRAY_P {$$ = makeItemIs(jbvArray); }
263+
|IS_PNUMBER_P {$$ = makeItemIs(jbvNumeric); }
264+
|IS_POBJECT_P {$$ = makeItemIs(jbvObject); }
265+
|IS_PTEXT_P {$$ = makeItemIs(jbvString); }
266+
|IS_PBOOLEAN_P {$$ = makeItemIs(jbvBool); }
244267
;
245268

246269
expr:
@@ -257,11 +280,17 @@ expr:
257280
*/
258281
key:
259282
STRING_P{$$ =$1; }
283+
|IN_P{$$ =$1; }
284+
|IS_P{$$ =$1; }
285+
|NULL_P{$$ =$1; }
260286
|TRUE_P{$$ =$1; }
287+
|ARRAY_P{$$ =$1; }
261288
|FALSE_P{$$ =$1; }
289+
|NUMBER_P{$$ =$1; }
290+
|OBJECT_P{$$ =$1; }
291+
|TEXT_P{$$ =$1; }
292+
|BOOLEAN_P{$$ =$1; }
262293
|NUMERIC_P{$$ =$1; }
263-
|NULL_P{$$ =$1; }
264-
|IN_P{$$ =$1; }
265294
;
266295

267296
path_elem:

‎jsquery_io.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item)
5050
casejqiBool:
5151
appendBinaryStringInfo(buf, (char*)&item->boolean,sizeof(item->boolean));
5252
break;
53+
casejqiIs:
54+
appendBinaryStringInfo(buf, (char*)&item->isType,sizeof(item->isType));
55+
break;
5356
casejqiArray:
5457
{
5558
int32i,arrayStart;
@@ -203,13 +206,37 @@ printJsQueryItem(StringInfo buf, JsQueryItem *v, bool inKey, bool printBracketes
203206
appendStringInfoString(buf,
204207
DatumGetCString(DirectFunctionCall1(numeric_out,
205208
PointerGetDatum(jsqGetNumeric(v)))));
206-
break;
209+
break;
207210
casejqiBool:
208211
if (jsqGetBool(v))
209212
appendBinaryStringInfo(buf,"true",4);
210213
else
211214
appendBinaryStringInfo(buf,"false",5);
212215
break;
216+
casejqiIs:
217+
appendBinaryStringInfo(buf," IS ",4);
218+
switch(jsqGetIsType(v))
219+
{
220+
casejbvString:
221+
appendBinaryStringInfo(buf,"STRING",6);
222+
break;
223+
casejbvNumeric:
224+
appendBinaryStringInfo(buf,"NUMBER",6);
225+
break;
226+
casejbvBool:
227+
appendBinaryStringInfo(buf,"BOOLEAN",7);
228+
break;
229+
casejbvArray:
230+
appendBinaryStringInfo(buf,"ARRAY",5);
231+
break;
232+
casejbvObject:
233+
appendBinaryStringInfo(buf,"OBJECT",6);
234+
break;
235+
default:
236+
elog(ERROR,"Unknown type for IS: %d",jsqGetIsType(v));
237+
break;
238+
}
239+
break;
213240
casejqiArray:
214241
if (printBracketes)
215242
appendStringInfoChar(buf,'[');

‎jsquery_op.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,30 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb)
427427
jsqGetArg(jsq,&elem);
428428
res=executeExpr(&elem,jsq->type,jb);
429429
break;
430+
casejqiIs:
431+
if (JsonbType(jb)==jbvScalar)
432+
{
433+
JsonbIterator*it;
434+
int32r;
435+
JsonbValuev;
436+
437+
it=JsonbIteratorInit(jb->val.binary.data);
438+
439+
r=JsonbIteratorNext(&it,&v, true);
440+
Assert(r==WJB_BEGIN_ARRAY);
441+
Assert(v.val.array.rawScalar==1);
442+
Assert(v.val.array.nElems==1);
443+
444+
r=JsonbIteratorNext(&it,&v, true);
445+
Assert(r==WJB_ELEM);
446+
447+
res= (jsqGetIsType(jsq)==JsonbType(&v));
448+
}
449+
else
450+
{
451+
res= (jsqGetIsType(jsq)==JsonbType(jb));
452+
}
453+
break;
430454
default:
431455
elog(ERROR,"Wrong state: %d",jsq->type);
432456
}

‎jsquery_scan.l

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,22 @@ typedef struct keyword
191191
char*keyword;
192192
} keyword;
193193

194+
/*
195+
* Array of key words should be sorted by length and then
196+
* alphabetical order
197+
*/
198+
194199
static keyword keywords[] = {
195-
{2,false,IN_P,"in" },
200+
{2,false,IN_P,"in"},
201+
{2,false,IS_P,"is"},
196202
{4,true,NULL_P,"null"},
197203
{4,true,TRUE_P,"true"},
198-
{5,true,FALSE_P,"false"}
204+
{5,false,ARRAY_P,"array"},
205+
{5,true,FALSE_P,"false"},
206+
{6,false,NUMBER_P,"number"},
207+
{6,false,OBJECT_P,"object"},
208+
{6,false,TEXT_P,"string"},
209+
{7,false,BOOLEAN_P,"boolean"},
199210
};
200211

201212
staticint
@@ -212,7 +223,7 @@ checkSpecialVal()
212223

213224
while(StopLow < StopHigh)
214225
{
215-
StopMiddle = StopLow + (StopHigh - StopLow)/2;
226+
StopMiddle = StopLow + ((StopHigh - StopLow)>>1);
216227

217228
if (StopMiddle->len == scanstring.len)
218229
diff =pg_strncasecmp(StopMiddle->keyword, scanstring.val, scanstring.len);

‎jsquery_support.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ jsqInitByBuffer(JsQueryItem *v, char *base, int32 pos)
7979
/* follow next */
8080
casejqiNumeric:
8181
casejqiBool:
82+
casejqiIs:
8283
v->value.data=base+pos;
8384
break;
8485
casejqiArray:
@@ -186,6 +187,14 @@ jsqGetNumeric(JsQueryItem *v)
186187
return (Numeric)v->value.data;
187188
}
188189

190+
int32
191+
jsqGetIsType(JsQueryItem*v)
192+
{
193+
Assert(v->type=jqiIs);
194+
195+
return (int32)*v->value.data;
196+
}
197+
189198
char*
190199
jsqGetString(JsQueryItem*v,int32*len)
191200
{

‎sql/jsquery.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,20 @@ select 'a\r = "\abcdx"'::jsquery AS err;
193193
select'a\r = "\\abcdx"'::jsquery;
194194
select'a\r = x"\\abcd"'::jsqueryAS err;
195195

196+
--IS
197+
198+
select'as IS boolean | as is ARRAY | as is ObJect | as is Number | as is string'::jsquery;
199+
select'{"as": "xxx"}' @@'as IS string'::jsquery;
200+
select'{"as": "xxx"}' @@'as IS boolean | as is ARRAY | as is ObJect | as is Number'::jsquery;
201+
select'{"as": 5}' @@'as is Number'::jsquery;
202+
select'{"as": true}' @@'as is boolean'::jsquery;
203+
select'{"as": false}' @@'as is boolean'::jsquery;
204+
select'{"as": "false"}' @@'as is boolean'::jsquery;
205+
select'["xxx"]' @@'$ IS array'::jsquery;
206+
select'{"as": false}' @@'$ IS object'::jsquery;
207+
select'"xxx"' @@'$ IS string'::jsquery;
208+
select'"xxx"' @@'$ IS number'::jsquery;
209+
196210
---table and index
197211

198212
selectcount(*)from test_jsquerywhere (v->>'review_helpful_votes')::int4>0;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp