Skip to content

Commit a872917

Browse files
committed
Support Basic INSERT INTO
Now were cooking with gas
1 parent 688de90 commit a872917

File tree

5 files changed

+275
-7
lines changed

5 files changed

+275
-7
lines changed

regress/expected/new_cypher.out

+7
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,13 @@ SELECT a.i FROM tst a;
205205
---
206206
(0 rows)
207207

208+
INSERT INTO tst SELECT 'Hello';
209+
SELECT * FROM tst;
210+
i
211+
-------
212+
Hello
213+
(1 row)
214+
208215
DROP GRAPH new_cypher CASCADE;
209216
NOTICE: drop cascades to 2 other objects
210217
DETAIL: drop cascades to table new_cypher._ag_label_vertex

regress/sql/new_cypher.sql

+4
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,9 @@ SELECT a.i FROM tst a
104104
INTERSECT
105105
SELECT a.i FROM tst a;
106106

107+
INSERT INTO tst SELECT 'Hello';
108+
109+
SELECT * FROM tst;
110+
107111
DROP GRAPH new_cypher CASCADE;
108112
DROP GRAPH new_cypher_2 CASCADE;

src/backend/parser/cypher_analyze.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,9 @@ CypherCreateCommandTag(Node *parsetree)
11701170
} else if (IsA(n, CreateStmt)) {
11711171
tag = CMDTAG_CREATE_TABLE;
11721172
break;
1173+
} else if (IsA(n, InsertStmt)) {
1174+
tag = CMDTAG_INSERT;
1175+
break;
11731176
}
11741177
}
11751178
}
@@ -1397,7 +1400,7 @@ cypher_parse_analyze(RawStmt *parseTree, const char *sourceText,
13971400
if (list_length(parseTree->stmt) == 1) {
13981401
Node *n = linitial(parseTree->stmt);
13991402

1400-
if (IsA(n, CreateExtensionStmt) || IsA(n,CreateStmt) || IsA(n, SelectStmt)) {
1403+
if (IsA(n, CreateExtensionStmt) || IsA(n,CreateStmt) || IsA(n, SelectStmt) || IsA(n, InsertStmt)) {
14011404
query = parse_analyze((makeRawStmt(n, 0)), sourceText, paramTypes, numParams,
14021405
queryEnv);
14031406

src/backend/parser/cypher_gram.y

+258-6
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ static void insertSelectOptions(SelectStmt *stmt,
8888
SelectLimit *limitClause,
8989
WithClause *withClause,
9090
ag_scanner_t yyscanner);
91+
92+
static Node *makeStringConst(char *str, int location);
93+
static Node *makeIntConst(int val, int location);
94+
static Node *makeFloatConst(char *str, int location);
95+
static Node *makeBoolAConst(bool state, int location);
96+
static Node *makeNullAConst(int location);
97+
static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
9198
%}
9299

93100
%locations
@@ -121,6 +128,7 @@ static void insertSelectOptions(SelectStmt *stmt,
121128
struct Alias *alias;
122129
struct GroupClause *groupclause;
123130
struct SortBy *sortby;
131+
struct InsertStmt *istmt;
124132
}
125133

126134
%token <integer> INTEGER
@@ -142,7 +150,7 @@ static void insertSelectOptions(SelectStmt *stmt,
142150
GLOBAL GRAPH GROUP GROUPS GROUPING
143151
FALSE_P FILTER FIRST_P FOLLOWING FROM
144152
HAVING
145-
IF ILIKE IN INHERITS INTERSECT INTERVAL IS
153+
IF ILIKE IN INHERITS INTERSECT INSERT INTERVAL INTO IS
146154
LAST_P LIKE LIMIT LOCAL LOCALTIME LOCALTIMESTAMP
147155
MATCH MERGE
148156
NO NOT NULL_P NULLS_LA
@@ -165,14 +173,15 @@ static void insertSelectOptions(SelectStmt *stmt,
165173

166174
%type <node> CreateExtensionStmt CreateGraphStmt CreateTableStmt
167175
DropGraphStmt
176+
InsertStmt
168177
UseGraphStmt
169178
SelectStmt
170179

171180
%type <node> select_no_parens select_with_parens select_clause
172181
simple_select
173182

174183
%type <node> where_clause
175-
a_expr b_expr c_expr indirection_el
184+
a_expr b_expr c_expr AexprConst indirection_el
176185
columnref having_clause
177186

178187
%type <integer> set_quantifier
@@ -273,8 +282,8 @@ static void insertSelectOptions(SelectStmt *stmt,
273282

274283
%type <typnam> Typename SimpleTypename GenericType func_type
275284

276-
%type <range> qualified_name
277-
285+
%type <range> qualified_name insert_target
286+
%type <istmt> insert_rest
278287
%type <node> TableElement
279288
%type <node> columnDef
280289

@@ -372,6 +381,7 @@ stmt:
372381
| CreateExtensionStmt semicolon_opt { extra->result = list_make1($1); }
373382
| CreateTableStmt semicolon_opt { extra->result = list_make1($1); }
374383
| DropGraphStmt semicolon_opt { extra->result = list_make1($1); }
384+
| InsertStmt semicolon_opt { extra->result = list_make1($1); }
375385
| UseGraphStmt semicolon_opt { extra->result = list_make1($1); }
376386
| SelectStmt semicolon_opt { extra->result = list_make1($1); }
377387
;
@@ -398,6 +408,7 @@ cypher_stmt:
398408
$$ = list_make1(make_set_op(SETOP_EXCEPT, $3, $1, $4));
399409
}
400410
;
411+
401412
/*****************************************************************************
402413
*
403414
* QUERY:
@@ -939,6 +950,90 @@ sortby: a_expr USING all_op opt_nulls_order
939950
}
940951
;
941952

953+
954+
/*****************************************************************************
955+
*
956+
* QUERY:
957+
* INSERT STATEMENTS
958+
*
959+
*****************************************************************************/
960+
961+
InsertStmt:
962+
/* opt_with_clause INSERT INTO insert_target insert_rest
963+
opt_on_conflict returning_clause
964+
{
965+
$5->relation = $4;
966+
$5->onConflictClause = $6;
967+
$5->returningList = $7;
968+
$5->withClause = $1;
969+
$$ = (Node *) $5;
970+
}
971+
*/
972+
INSERT INTO insert_target insert_rest
973+
//opt_on_conflict returning_clause
974+
{
975+
$4->relation = $3;
976+
$4->onConflictClause = NULL;
977+
$4->returningList = NULL;
978+
$4->withClause = NULL;
979+
980+
$$ = (Node *) $4;
981+
}
982+
;
983+
984+
/*
985+
* Can't easily make AS optional here, because VALUES in insert_rest would
986+
* have a shift/reduce conflict with VALUES as an optional alias. We could
987+
* easily allow unreserved_keywords as optional aliases, but that'd be an odd
988+
* divergence from other places. So just require AS for now.
989+
*/
990+
insert_target:
991+
qualified_name
992+
{
993+
$$ = $1;
994+
}
995+
| qualified_name AS ColId
996+
{
997+
$1->alias = makeAlias($3, NIL);
998+
$$ = $1;
999+
}
1000+
;
1001+
1002+
insert_rest:
1003+
SelectStmt
1004+
{
1005+
$$ = makeNode(InsertStmt);
1006+
$$->cols = NIL;
1007+
$$->selectStmt = $1;
1008+
}/*
1009+
| OVERRIDING override_kind VALUE_P SelectStmt
1010+
{
1011+
$$ = makeNode(InsertStmt);
1012+
$$->cols = NIL;
1013+
$$->override = $2;
1014+
$$->selectStmt = $4;
1015+
}
1016+
| '(' insert_column_list ')' SelectStmt
1017+
{
1018+
$$ = makeNode(InsertStmt);
1019+
$$->cols = $2;
1020+
$$->selectStmt = $4;
1021+
}
1022+
| '(' insert_column_list ')' OVERRIDING override_kind VALUE_P SelectStmt
1023+
{
1024+
$$ = makeNode(InsertStmt);
1025+
$$->cols = $2;
1026+
$$->override = $5;
1027+
$$->selectStmt = $7;
1028+
}
1029+
| DEFAULT VALUES
1030+
{
1031+
$$ = makeNode(InsertStmt);
1032+
$$->cols = NIL;
1033+
$$->selectStmt = NULL;
1034+
}*/
1035+
;
1036+
9421037
CreateGraphStmt:
9431038
CREATE GRAPH IDENTIFIER
9441039
{
@@ -2521,8 +2616,8 @@ b_expr: c_expr
25212616
* ambiguity to the b_expr syntax.
25222617
*/
25232618
c_expr: columnref { $$ = $1; }
2524-
/*| AexprConst { $$ = $1; }
2525-
| PARAM opt_indirection
2619+
| AexprConst { $$ = $1; }
2620+
/*| PARAM opt_indirection
25262621
{
25272622
ParamRef *p = makeNode(ParamRef);
25282623
p->number = $1;
@@ -2637,6 +2732,94 @@ c_expr: columnref { $$ = $1; }
26372732
}*/
26382733
;
26392734

2735+
2736+
/*
2737+
* Constants
2738+
*/
2739+
AexprConst: Iconst
2740+
{
2741+
$$ = makeIntConst($1, @1);
2742+
}
2743+
| DECIMAL
2744+
{
2745+
$$ = makeFloatConst($1, @1);
2746+
}
2747+
| Sconst
2748+
{
2749+
$$ = makeStringConst($1, @1);
2750+
}
2751+
/*| BCONST
2752+
{
2753+
$$ = makeBitStringConst($1, @1);
2754+
}
2755+
| XCONST
2756+
{
2757+
2758+
$$ = makeBitStringConst($1, @1);
2759+
}
2760+
| func_name Sconst
2761+
{
2762+
TypeName *t = makeTypeNameFromNameList($1);
2763+
t->location = @1;
2764+
$$ = makeStringConstCast($2, @2, t);
2765+
}
2766+
| func_name '(' func_arg_list opt_sort_clause ')' Sconst
2767+
{
2768+
TypeName *t = makeTypeNameFromNameList($1);
2769+
ListCell *lc;
2770+
2771+
foreach(lc, $3)
2772+
{
2773+
NamedArgExpr *arg = (NamedArgExpr *) lfirst(lc);
2774+
2775+
if (IsA(arg, NamedArgExpr))
2776+
ereport(ERROR,
2777+
(errcode(ERRCODE_SYNTAX_ERROR),
2778+
errmsg("type modifier cannot have parameter name"),
2779+
parser_errposition(arg->location)));
2780+
}
2781+
if ($4 != NIL)
2782+
ereport(ERROR,
2783+
(errcode(ERRCODE_SYNTAX_ERROR),
2784+
errmsg("type modifier cannot have ORDER BY"),
2785+
parser_errposition(@4)));
2786+
2787+
t->typmods = $3;
2788+
t->location = @1;
2789+
$$ = makeStringConstCast($6, @6, t);
2790+
}
2791+
| ConstTypename Sconst
2792+
{
2793+
$$ = makeStringConstCast($2, @2, $1);
2794+
}
2795+
| ConstInterval Sconst opt_interval
2796+
{
2797+
TypeName *t = $1;
2798+
t->typmods = $3;
2799+
$$ = makeStringConstCast($2, @2, t);
2800+
}
2801+
| ConstInterval '(' Iconst ')' Sconst
2802+
{
2803+
TypeName *t = $1;
2804+
t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
2805+
makeIntConst($3, @3));
2806+
$$ = makeStringConstCast($5, @5, t);
2807+
}*/
2808+
| TRUE_P
2809+
{
2810+
$$ = makeBoolAConst(true, @1);
2811+
}
2812+
| FALSE_P
2813+
{
2814+
$$ = makeBoolAConst(false, @1);
2815+
}
2816+
| NULL_P
2817+
{
2818+
$$ = makeNullAConst(@1);
2819+
}
2820+
;
2821+
2822+
26402823
/*****************************************************************************
26412824
*
26422825
* Names and constants
@@ -4708,4 +4891,73 @@ makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
47084891
n->larg = (SelectStmt *) larg;
47094892
n->rarg = (SelectStmt *) rarg;
47104893
return (Node *) n;
4894+
}
4895+
4896+
static Node *
4897+
makeTypeCast(Node *arg, TypeName *typename, int location)
4898+
{
4899+
TypeCast *n = makeNode(TypeCast);
4900+
n->arg = arg;
4901+
n->typeName = typename;
4902+
n->location = location;
4903+
return (Node *) n;
4904+
}
4905+
4906+
static Node *
4907+
makeStringConst(char *str, int location)
4908+
{
4909+
A_Const *n = makeNode(A_Const);
4910+
4911+
n->val.type = T_String;
4912+
n->val.val.str = str;
4913+
n->location = location;
4914+
4915+
return (Node *)n;
4916+
}
4917+
4918+
static Node *
4919+
makeIntConst(int val, int location)
4920+
{
4921+
A_Const *n = makeNode(A_Const);
4922+
4923+
n->val.type = T_Integer;
4924+
n->val.val.ival = val;
4925+
n->location = location;
4926+
4927+
return (Node *)n;
4928+
}
4929+
4930+
static Node *
4931+
makeFloatConst(char *str, int location)
4932+
{
4933+
A_Const *n = makeNode(A_Const);
4934+
4935+
n->val.type = T_Float;
4936+
n->val.val.str = str;
4937+
n->location = location;
4938+
4939+
return (Node *)n;
4940+
}
4941+
4942+
static Node *
4943+
makeBoolAConst(bool state, int location)
4944+
{
4945+
A_Const *n = makeNode(A_Const);
4946+
4947+
n->val.type = T_String;
4948+
n->val.val.str = (state ? "t" : "f");
4949+
n->location = location;
4950+
4951+
return makeTypeCast((Node *)n, SystemTypeName("bool"), -1);
4952+
}
4953+
4954+
static Node *
4955+
makeNullAConst(int location)
4956+
{
4957+
A_Const *n = makeNode(A_Const);
4958+
4959+
n->val.type = T_Null;
4960+
n->location = location;
4961+
4962+
return (Node *)n;
47114963
}

0 commit comments

Comments
 (0)