should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,756 @@
/*
* The signature of this function is required by bison. However, we
* ignore the passed yylloc and instead use the last token position
* available from the scanner.
*/
static void
base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg)
{
parser_yyerror(msg);
}
static PGRawStmt *
makeRawStmt(PGNode *stmt, int stmt_location)
{
PGRawStmt *rs = makeNode(PGRawStmt);
rs->stmt = stmt;
rs->stmt_location = stmt_location;
rs->stmt_len = 0; /* might get changed later */
return rs;
}
/* Adjust a PGRawStmt to reflect that it doesn't run to the end of the string */
static void
updateRawStmtEnd(PGRawStmt *rs, int end_location)
{
/*
* If we already set the length, don't change it. This is for situations
* like "select foo ;; select bar" where the same statement will be last
* in the string for more than one semicolon.
*/
if (rs->stmt_len > 0)
return;
/* OK, update length of PGRawStmt */
rs->stmt_len = end_location - rs->stmt_location;
}
static PGNode *
makeColumnRef(char *colname, PGList *indirection,
int location, core_yyscan_t yyscanner)
{
/*
* Generate a PGColumnRef node, with an PGAIndirection node added if there
* is any subscripting in the specified indirection list. However,
* any field selection at the start of the indirection list must be
* transposed into the "fields" part of the PGColumnRef node.
*/
PGColumnRef *c = makeNode(PGColumnRef);
int nfields = 0;
PGListCell *l;
c->location = location;
foreach(l, indirection)
{
if (IsA(lfirst(l), PGAIndices))
{
PGAIndirection *i = makeNode(PGAIndirection);
if (nfields == 0)
{
/* easy case - all indirection goes to PGAIndirection */
c->fields = list_make1(makeString(colname));
i->indirection = check_indirection(indirection, yyscanner);
}
else
{
/* got to split the list in two */
i->indirection = check_indirection(list_copy_tail(indirection,
nfields),
yyscanner);
indirection = list_truncate(indirection, nfields);
c->fields = lcons(makeString(colname), indirection);
}
i->arg = (PGNode *) c;
return (PGNode *) i;
}
else if (IsA(lfirst(l), PGAStar))
{
/* We only allow '*' at the end of a PGColumnRef */
if (lnext(l) != NULL)
parser_yyerror("improper use of \"*\"");
}
nfields++;
}
/* No subscripting, so all indirection gets added to field list */
c->fields = lcons(makeString(colname), indirection);
return (PGNode *) c;
}
static PGNode *
makeTypeCast(PGNode *arg, PGTypeName *tpname, int trycast, int location)
{
PGTypeCast *n = makeNode(PGTypeCast);
n->arg = arg;
n->typeName = tpname;
n->tryCast = trycast;
n->location = location;
return (PGNode *) n;
}
static PGNode *
makeStringConst(const char *str, int location)
{
PGAConst *n = makeNode(PGAConst);
n->val.type = T_PGString;
n->val.val.str = (char *) str;
n->location = location;
return (PGNode *)n;
}
static PGNode *
makeStringConstCast(const char *str, int location, PGTypeName *tpname)
{
PGNode *s = makeStringConst(str, location);
return makeTypeCast(s, tpname, 0, -1);
}
static PGNode *
makeIntervalNode(char *str, int location, PGList *typmods) {
PGIntervalConstant *n = makeNode(PGIntervalConstant);
n->val_type = T_PGString;
n->sval = str;
n->location = location;
n->typmods = typmods;
return (PGNode *)n;
}
static PGNode *
makeIntervalNode(int val, int location, PGList *typmods) {
PGIntervalConstant *n = makeNode(PGIntervalConstant);
n->val_type = T_PGInteger;
n->ival = val;
n->location = location;
n->typmods = typmods;
return (PGNode *)n;
}
static PGNode *
makeIntervalNode(PGNode *arg, int location, PGList *typmods) {
PGIntervalConstant *n = makeNode(PGIntervalConstant);
n->val_type = T_PGAExpr;
n->eval = arg;
n->location = location;
n->typmods = typmods;
return (PGNode *)n;
}
static PGNode *
makeSampleSize(PGNode *sample_size, bool is_percentage) {
PGSampleSize *n = makeNode(PGSampleSize);
n->sample_size = sample_size;
n->is_percentage = is_percentage;
return (PGNode *)n;
}
static PGNode *
makeSampleOptions(PGNode *sample_size, char *method, int *seed, int location) {
PGSampleOptions *n = makeNode(PGSampleOptions);
n->sample_size = sample_size;
n->method = method;
if (seed) {
n->has_seed = true;
n->seed = *seed;
}
n->location = location;
return (PGNode *)n;
}
/* makeLimitPercent()
* Make limit percent node
*/
static PGNode *
makeLimitPercent(PGNode *limit_percent) {
PGLimitPercent *n = makeNode(PGLimitPercent);
n->limit_percent = limit_percent;
return (PGNode *)n;
}
static PGNode *
makeIntConst(int val, int location)
{
PGAConst *n = makeNode(PGAConst);
n->val.type = T_PGInteger;
n->val.val.ival = val;
n->location = location;
return (PGNode *)n;
}
static PGNode *
makeFloatConst(char *str, int location)
{
PGAConst *n = makeNode(PGAConst);
n->val.type = T_PGFloat;
n->val.val.str = str;
n->location = location;
return (PGNode *)n;
}
static PGNode *
makeBitStringConst(char *str, int location)
{
PGAConst *n = makeNode(PGAConst);
n->val.type = T_PGBitString;
n->val.val.str = str;
n->location = location;
return (PGNode *)n;
}
static PGNode *
makeNullAConst(int location)
{
PGAConst *n = makeNode(PGAConst);
n->val.type = T_PGNull;
n->location = location;
return (PGNode *)n;
}
static PGNode *
makeAConst(PGValue *v, int location)
{
PGNode *n;
switch (v->type)
{
case T_PGFloat:
n = makeFloatConst(v->val.str, location);
break;
case T_PGInteger:
n = makeIntConst(v->val.ival, location);
break;
case T_PGString:
default:
n = makeStringConst(v->val.str, location);
break;
}
return n;
}
/* makeBoolAConst()
* Create an PGAConst string node and put it inside a boolean cast.
*/
static PGNode *
makeBoolAConst(bool state, int location)
{
PGAConst *n = makeNode(PGAConst);
n->val.type = T_PGString;
n->val.val.str = (state ? (char*) "t" : (char*) "f");
n->location = location;
return makeTypeCast((PGNode *)n, SystemTypeName("bool"), 0, -1);
}
/* check_qualified_name --- check the result of qualified_name production
*
* It's easiest to let the grammar production for qualified_name allow
* subscripts and '*', which we then must reject here.
*/
static void
check_qualified_name(PGList *names, core_yyscan_t yyscanner)
{
PGListCell *i;
foreach(i, names)
{
if (!IsA(lfirst(i), PGString))
parser_yyerror("syntax error");
}
}
/* check_func_name --- check the result of func_name production
*
* It's easiest to let the grammar production for func_name allow subscripts
* and '*', which we then must reject here.
*/
static PGList *
check_func_name(PGList *names, core_yyscan_t yyscanner)
{
PGListCell *i;
foreach(i, names)
{
if (!IsA(lfirst(i), PGString))
parser_yyerror("syntax error");
}
return names;
}
/* check_indirection --- check the result of indirection production
*
* We only allow '*' at the end of the list, but it's hard to enforce that
* in the grammar, so do it here.
*/
static PGList *
check_indirection(PGList *indirection, core_yyscan_t yyscanner)
{
PGListCell *l;
foreach(l, indirection)
{
if (IsA(lfirst(l), PGAStar))
{
if (lnext(l) != NULL)
parser_yyerror("improper use of \"*\"");
}
}
return indirection;
}
/* makeParamRef
* Creates a new PGParamRef node
*/
static PGNode* makeParamRef(int number, int location)
{
PGParamRef *p = makeNode(PGParamRef);
p->number = number;
p->location = location;
p->name = NULL;
return (PGNode *) p;
}
/* makeNamedParamRef
* Creates a new PGParamRef node
*/
static PGNode* makeNamedParamRef(char *name, int location)
{
PGParamRef *p = (PGParamRef *)makeParamRef(0, location);
p->name = name;
return (PGNode *) p;
}
/* insertSelectOptions()
* Insert ORDER BY, etc into an already-constructed SelectStmt.
*
* This routine is just to avoid duplicating code in PGSelectStmt productions.
*/
static void
insertSelectOptions(PGSelectStmt *stmt,
PGList *sortClause, PGList *lockingClause,
PGNode *limitOffset, PGNode *limitCount, PGNode *isLimitOffsetFirst,
PGWithClause *withClause,
core_yyscan_t yyscanner)
{
if (stmt->type != T_PGSelectStmt) {
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("DESCRIBE/SHOW/SUMMARIZE with CTE/ORDER BY/... not allowed - wrap the statement in a subquery instead"),
parser_errposition(exprLocation((PGNode *) stmt))));
}
Assert(IsA(stmt, PGSelectStmt));
/*
* Tests here are to reject constructs like
* (SELECT foo ORDER BY bar) ORDER BY baz
*/
if (sortClause)
{
if (stmt->sortClause)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("multiple ORDER BY clauses not allowed"),
parser_errposition(exprLocation((PGNode *) sortClause))));
stmt->sortClause = sortClause;
}
/* We can handle multiple locking clauses, though */
stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause);
if (limitOffset)
{
if (stmt->limitOffset)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("multiple OFFSET clauses not allowed"),
parser_errposition(exprLocation(limitOffset))));
stmt->limitOffset = limitOffset;
}
if (limitCount)
{
if (stmt->limitCount)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("multiple LIMIT clauses not allowed"),
parser_errposition(exprLocation(limitCount))));
stmt->limitCount = limitCount;
}
if (limitOffset == isLimitOffsetFirst) {
stmt->offset_first = true;
}
if (withClause)
{
if (stmt->withClause)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("multiple WITH clauses not allowed"),
parser_errposition(exprLocation((PGNode *) withClause))));
stmt->withClause = withClause;
}
}
static PGNode *
makeSetOp(PGSetOperation op, bool all, PGNode *larg, PGNode *rarg)
{
PGSelectStmt *n = makeNode(PGSelectStmt);
n->op = op;
n->all = all;
n->larg = larg;
n->rarg = rarg;
return (PGNode *) n;
}
/* SystemFuncName()
* Build a properly-qualified reference to a built-in function.
*/
PGList *
SystemFuncName(const char *name)
{
return list_make2(makeString(DEFAULT_SCHEMA), makeString(name));
}
/* SystemTypeName()
* Build a properly-qualified reference to a built-in type.
*
* typmod is defaulted, but may be changed afterwards by caller.
* Likewise for the location.
*/
PGTypeName *
SystemTypeName(const char *name)
{
return makeTypeNameFromNameList(list_make1(makeString(name)));
}
/* doNegate()
* Handle negation of a numeric constant.
*
* Formerly, we did this here because the optimizer couldn't cope with
* indexquals that looked like "var = -4" --- it wants "var = const"
* and a unary minus operator applied to a constant didn't qualify.
* As of Postgres 7.0, that problem doesn't exist anymore because there
* is a constant-subexpression simplifier in the optimizer. However,
* there's still a good reason for doing this here, which is that we can
* postpone committing to a particular internal representation for simple
* negative constants. It's better to leave "-123.456" in string form
* until we know what the desired type is.
*/
static PGNode *
doNegate(PGNode *n, int location)
{
if (IsA(n, PGAConst))
{
PGAConst *con = (PGAConst *)n;
/* report the constant's location as that of the '-' sign */
con->location = location;
if (con->val.type == T_PGInteger)
{
con->val.val.ival = -con->val.val.ival;
return n;
}
if (con->val.type == T_PGFloat)
{
doNegateFloat(&con->val);
return n;
}
}
return (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "-", NULL, n, location);
}
static void
doNegateFloat(PGValue *v)
{
char *oldval = v->val.str;
Assert(IsA(v, PGFloat));
if (*oldval == '+')
oldval++;
if (*oldval == '-')
v->val.str = oldval+1; /* just strip the '-' */
else
v->val.str = psprintf("-%s", oldval);
}
static PGNode *
makeAndExpr(PGNode *lexpr, PGNode *rexpr, int location)
{
PGNode *lexp = lexpr;
/* Look through AEXPR_PAREN nodes so they don't affect flattening */
while (IsA(lexp, PGAExpr) &&
((PGAExpr *) lexp)->kind == AEXPR_PAREN)
lexp = ((PGAExpr *) lexp)->lexpr;
/* Flatten "a AND b AND c ..." to a single PGBoolExpr on sight */
if (IsA(lexp, PGBoolExpr))
{
PGBoolExpr *blexpr = (PGBoolExpr *) lexp;
if (blexpr->boolop == PG_AND_EXPR)
{
blexpr->args = lappend(blexpr->args, rexpr);
return (PGNode *) blexpr;
}
}
return (PGNode *) makeBoolExpr(PG_AND_EXPR, list_make2(lexpr, rexpr), location);
}
static PGNode *
makeOrExpr(PGNode *lexpr, PGNode *rexpr, int location)
{
PGNode *lexp = lexpr;
/* Look through AEXPR_PAREN nodes so they don't affect flattening */
while (IsA(lexp, PGAExpr) &&
((PGAExpr *) lexp)->kind == AEXPR_PAREN)
lexp = ((PGAExpr *) lexp)->lexpr;
/* Flatten "a OR b OR c ..." to a single PGBoolExpr on sight */
if (IsA(lexp, PGBoolExpr))
{
PGBoolExpr *blexpr = (PGBoolExpr *) lexp;
if (blexpr->boolop == PG_OR_EXPR)
{
blexpr->args = lappend(blexpr->args, rexpr);
return (PGNode *) blexpr;
}
}
return (PGNode *) makeBoolExpr(PG_OR_EXPR, list_make2(lexpr, rexpr), location);
}
static PGNode *
makeNotExpr(PGNode *expr, int location)
{
return (PGNode *) makeBoolExpr(PG_NOT_EXPR, list_make1(expr), location);
}
/* Separate PGConstraint nodes from COLLATE clauses in a */
static void
SplitColQualList(PGList *qualList,
PGList **constraintList, PGCollateClause **collClause,
core_yyscan_t yyscanner)
{
PGListCell *cell;
PGListCell *prev;
PGListCell *next;
*collClause = NULL;
prev = NULL;
for (cell = list_head(qualList); cell; cell = next)
{
PGNode *n = (PGNode *) lfirst(cell);
next = lnext(cell);
if (IsA(n, PGConstraint))
{
/* keep it in list */
prev = cell;
continue;
}
if (IsA(n, PGCollateClause))
{
PGCollateClause *c = (PGCollateClause *) n;
if (*collClause)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("multiple COLLATE clauses not allowed"),
parser_errposition(c->location)));
*collClause = c;
}
else
elog(ERROR, "unexpected node type %d", (int) n->type);
/* remove non-Constraint nodes from qualList */
qualList = list_delete_cell(qualList, cell, prev);
}
*constraintList = qualList;
}
/*
* Process result of ConstraintAttributeSpec, and set appropriate bool flags
* in the output command node. Pass NULL for any flags the particular
* command doesn't support.
*/
static void
processCASbits(int cas_bits, int location, const char *constrType,
bool *deferrable, bool *initdeferred, bool *not_valid,
bool *no_inherit, core_yyscan_t yyscanner)
{
/* defaults */
if (deferrable)
*deferrable = false;
if (initdeferred)
*initdeferred = false;
if (not_valid)
*not_valid = false;
if (cas_bits & (CAS_DEFERRABLE | CAS_INITIALLY_DEFERRED))
{
if (deferrable)
*deferrable = true;
else
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
/* translator: %s is CHECK, UNIQUE, or similar */
errmsg("%s constraints cannot be marked DEFERRABLE",
constrType),
parser_errposition(location)));
}
if (cas_bits & CAS_INITIALLY_DEFERRED)
{
if (initdeferred)
*initdeferred = true;
else
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
/* translator: %s is CHECK, UNIQUE, or similar */
errmsg("%s constraints cannot be marked DEFERRABLE",
constrType),
parser_errposition(location)));
}
if (cas_bits & CAS_NOT_VALID)
{
if (not_valid)
*not_valid = true;
else
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
/* translator: %s is CHECK, UNIQUE, or similar */
errmsg("%s constraints cannot be marked NOT VALID",
constrType),
parser_errposition(location)));
}
if (cas_bits & CAS_NO_INHERIT)
{
if (no_inherit)
*no_inherit = true;
else
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
/* translator: %s is CHECK, UNIQUE, or similar */
errmsg("%s constraints cannot be marked NO INHERIT",
constrType),
parser_errposition(location)));
}
}
/*----------
* Recursive view transformation
*
* Convert
*
* CREATE RECURSIVE VIEW relname (aliases) AS query
*
* to
*
* CREATE VIEW relname (aliases) AS
* WITH RECURSIVE relname (aliases) AS (query)
* SELECT aliases FROM relname
*
* Actually, just the WITH ... part, which is then inserted into the original
* view as the query.
* ----------
*/
static PGNode *
makeRecursiveViewSelect(char *relname, PGList *aliases, PGNode *query)
{
PGSelectStmt *s = makeNode(PGSelectStmt);
PGWithClause *w = makeNode(PGWithClause);
PGCommonTableExpr *cte = makeNode(PGCommonTableExpr);
PGList *tl = NIL;
PGListCell *lc;
/* create common table expression */
cte->ctename = relname;
cte->aliascolnames = aliases;
cte->ctequery = query;
cte->location = -1;
/* create WITH clause and attach CTE */
w->recursive = true;
w->ctes = list_make1(cte);
w->location = -1;
/* create target list for the new SELECT from the alias list of the
* recursive view specification */
foreach (lc, aliases)
{
PGResTarget *rt = makeNode(PGResTarget);
rt->name = NULL;
rt->indirection = NIL;
rt->val = makeColumnRef(strVal(lfirst(lc)), NIL, -1, 0);
rt->location = -1;
tl = lappend(tl, rt);
}
/* create new SELECT combining WITH clause, target list, and fake FROM
* clause */
s->withClause = w;
s->targetList = tl;
s->fromClause = list_make1(makeRangeVar(NULL, relname, -1));
return (PGNode *) s;
}
/* parser_init()
* Initialize to parse one query string
*/
void
parser_init(base_yy_extra_type *yyext)
{
yyext->parsetree = NIL; /* in case grammar forgets to set it */
}
#undef yyparse
#undef yylex
#undef yyerror
#undef yylval
#undef yychar
#undef yydebug
#undef yynerrs
#undef yylloc
} // namespace duckdb_libpgquery

View File

@@ -0,0 +1,216 @@
/*#define YYDEBUG 1*/
/*-------------------------------------------------------------------------
*
* gram.y
* POSTGRESQL BISON rules/actions
*
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/backend/parser/gram.y
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
* Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
* Andrew Yu Oct, 1994 lispy code conversion
*
* NOTES
* CAPITALS are used to represent terminal symbols.
* non-capitals are used to represent non-terminals.
*
* In general, nothing in this file should initiate database accesses
* nor depend on changeable state (such as SET variables). If you do
* database accesses, your code will fail when we have aborted the
* current transaction and are just parsing commands to find the next
* ROLLBACK or COMMIT. If you make use of SET variables, then you
* will do the wrong thing in multi-query strings like this:
* SET constraint_exclusion TO off; SELECT * FROM foo;
* because the entire string is parsed by gram.y before the SET gets
* executed. Anything that depends on the database or changeable state
* should be handled during parse analysis so that it happens at the
* right time not the wrong time.
*
* WARNINGS
* If you use a list, make sure the datum is a node so that the printing
* routines work.
*
* Sometimes we assign constants to makeStrings. Make sure we don't free
* those.
*
*-------------------------------------------------------------------------
*/
#include "pg_functions.hpp"
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include "nodes/makefuncs.hpp"
#include "nodes/nodeFuncs.hpp"
#include "parser/gramparse.hpp"
#include "parser/parser.hpp"
#include "utils/datetime.hpp"
namespace duckdb_libpgquery {
#define DEFAULT_SCHEMA "main"
/*
* Location tracking support --- simpler than bison's default, since we only
* want to track the start position not the end position of each nonterminal.
*/
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
if ((N) > 0) \
(Current) = (Rhs)[1]; \
else \
(Current) = (-1); \
} while (0)
/*
* The above macro assigns -1 (unknown) as the parse location of any
* nonterminal that was reduced from an empty rule, or whose leftmost
* component was reduced from an empty rule. This is problematic
* for nonterminals defined like
* OptFooList: / * EMPTY * / { ... } | OptFooList Foo { ... } ;
* because we'll set -1 as the location during the first reduction and then
* copy it during each subsequent reduction, leaving us with -1 for the
* location even when the list is not empty. To fix that, do this in the
* action for the nonempty rule(s):
* if (@$ < 0) @$ = @2;
* (Although we have many nonterminals that follow this pattern, we only
* bother with fixing @$ like this when the nonterminal's parse location
* is actually referenced in some rule.)
*
* A cleaner answer would be to make YYLLOC_DEFAULT scan all the Rhs
* locations until it's found one that's not -1. Then we'd get a correct
* location for any nonterminal that isn't entirely empty. But this way
* would add overhead to every rule reduction, and so far there's not been
* a compelling reason to pay that overhead.
*/
/*
* Bison doesn't allocate anything that needs to live across parser calls,
* so we can easily have it use palloc instead of malloc. This prevents
* memory leaks if we error out during parsing. Note this only works with
* bison >= 2.0. However, in bison 1.875 the default is to use alloca()
* if possible, so there's not really much problem anyhow, at least if
* you're building with gcc.
*/
#define YYMALLOC palloc
#define YYFREE pfree
#define YYINITDEPTH 1000
/* yields an integer bitmask of these flags: */
#define CAS_NOT_DEFERRABLE 0x01
#define CAS_DEFERRABLE 0x02
#define CAS_INITIALLY_IMMEDIATE 0x04
#define CAS_INITIALLY_DEFERRED 0x08
#define CAS_NOT_VALID 0x10
#define CAS_NO_INHERIT 0x20
#define parser_yyerror(msg) scanner_yyerror(msg, yyscanner)
#define parser_errposition(pos) scanner_errposition(pos, yyscanner)
#if YYBISON == 1
// explicitly define stack growing support
// yacc cannot handle stack growing by default YYLTYPE is overriden - which the Postgres parser overrides with an `int`
// so we need to copy these definitions here explicitly
/* A type that is properly aligned for any stack member. */
union yyalloc
{
short int yyss;
YYSTYPE yyvs;
YYLTYPE yyls;
};
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
elements in the stack, and YYPTR gives the new location of the
stack. Advance YYPTR to a properly aligned location for the next
stack. */
# define YYSTACK_RELOCATE(Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack, Stack, yysize); \
Stack = &yyptr->Stack; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (YYID (0))
#endif
static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
const char *msg);
static PGRawStmt *makeRawStmt(PGNode *stmt, int stmt_location);
static void updateRawStmtEnd(PGRawStmt *rs, int end_location);
static PGNode *makeColumnRef(char *colname, PGList *indirection,
int location, core_yyscan_t yyscanner);
static PGNode *makeTypeCast(PGNode *arg, PGTypeName *tpname, int trycast, int location);
static PGNode *makeStringConst(const char *str, int location);
static PGNode *makeStringConstCast(const char *str, int location, PGTypeName *tpname);
static PGNode *makeIntervalNode(char *str, int location, PGList *typmods);
static PGNode *makeIntervalNode(int val, int location, PGList *typmods);
static PGNode *makeIntervalNode(PGNode *arg, int location, PGList *typmods);
static PGNode *makeSampleSize(PGNode *sample_size, bool is_percentage);
static PGNode *makeSampleOptions(PGNode *sample_size, char *method, int *seed, int location);
static PGNode *makeIntConst(int val, int location);
static PGNode *makeFloatConst(char *str, int location);
static PGNode *makeBitStringConst(char *str, int location);
static PGNode *makeNullAConst(int location);
static PGNode *makeAConst(PGValue *v, int location);
static PGNode *makeBoolAConst(bool state, int location);
static PGNode *makeParamRef(int number, int location);
static PGNode *makeNamedParamRef(char* name, int location);
static void check_qualified_name(PGList *names, core_yyscan_t yyscanner);
static PGList *check_func_name(PGList *names, core_yyscan_t yyscanner);
static PGList *check_indirection(PGList *indirection, core_yyscan_t yyscanner);
static void insertSelectOptions(PGSelectStmt *stmt,
PGList *sortClause, PGList *lockingClause,
PGNode *limitOffset, PGNode *limitCount, PGNode *isLimitOffsetFirst,
PGWithClause *withClause,
core_yyscan_t yyscanner);
static PGNode *makeSetOp(PGSetOperation op, bool all, PGNode *larg, PGNode *rarg);
static PGNode *doNegate(PGNode *n, int location);
static void doNegateFloat(PGValue *v);
static PGNode *makeAndExpr(PGNode *lexpr, PGNode *rexpr, int location);
static PGNode *makeOrExpr(PGNode *lexpr, PGNode *rexpr, int location);
static PGNode *makeNotExpr(PGNode *expr, int location);
static void SplitColQualList(PGList *qualList,
PGList **constraintList, PGCollateClause **collClause,
core_yyscan_t yyscanner);
static void processCASbits(int cas_bits, int location, const char *constrType,
bool *deferrable, bool *initdeferred, bool *not_valid,
bool *no_inherit, core_yyscan_t yyscanner);
static PGNode *makeRecursiveViewSelect(char *relname, PGList *aliases, PGNode *query);
static PGNode *makeLimitPercent(PGNode *limit_percent);

View File

@@ -0,0 +1,223 @@
%{
{{{ GRAMMAR_HEADER }}}
%}
#line 5 "third_party/libpg_query/grammar/grammar.y"
%pure-parser
%expect 0
%name-prefix="base_yy"
%locations
%parse-param {core_yyscan_t yyscanner}
%lex-param {core_yyscan_t yyscanner}
%union
{
core_YYSTYPE core_yystype;
/* these fields must match core_YYSTYPE: */
int ival;
char *str;
const char *keyword;
const char *conststr;
char chr;
bool boolean;
PGJoinType jtype;
PGDropBehavior dbehavior;
PGOnCommitAction oncommit;
PGOnCreateConflict oncreateconflict;
PGList *list;
PGNode *node;
PGValue *value;
PGObjectType objtype;
PGTypeName *typnam;
PGObjectWithArgs *objwithargs;
PGDefElem *defelt;
PGSortBy *sortby;
PGWindowDef *windef;
PGJoinExpr *jexpr;
PGIndexElem *ielem;
PGAlias *alias;
PGRangeVar *range;
PGIntoClause *into;
PGCTEMaterialize ctematerialize;
PGWithClause *with;
PGInferClause *infer;
PGOnConflictClause *onconflict;
PGOnConflictActionAlias onconflictshorthand;
PGAIndices *aind;
PGResTarget *target;
PGInsertStmt *istmt;
PGVariableSetStmt *vsetstmt;
PGOverridingKind override;
PGSortByDir sortorder;
PGSortByNulls nullorder;
PGIgnoreNulls ignorenulls;
PGConstrType constr;
PGLockClauseStrength lockstrength;
PGLockWaitPolicy lockwaitpolicy;
PGSubLinkType subquerytype;
PGViewCheckOption viewcheckoption;
PGInsertColumnOrder bynameorposition;
PGLoadInstallType loadinstalltype;
PGTransactionStmtType transactiontype;
PGMergeAction mergeaction;
}
%type <node> stmt
%type <list> stmtblock
%type <list> stmtmulti
{{{ TYPES }}}
/*
* Non-keyword token types. These are hard-wired into the "flex" lexer.
* They must be listed first so that their numeric codes do not depend on
* the set of keywords. PL/pgSQL depends on this so that it can share the
* same lexer. If you add/change tokens here, fix PL/pgSQL to match!
*
* DOT_DOT is unused in the core SQL grammar, and so will always provoke
* parse errors. It is needed by PL/pgSQL.
*/
%token <str> IDENT FCONST SCONST BCONST XCONST Op
%token <ival> ICONST PARAM
%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER INTEGER_DIVISION POWER_OF SINGLE_ARROW DOUBLE_ARROW SINGLE_COLON
%token LESS_EQUALS GREATER_EQUALS NOT_EQUALS
/*
* If you want to make any keyword changes, update the keyword table in
* src/include/parser/kwlist.h and add new keywords to the appropriate one
* of the reserved-or-not-so-reserved keyword lists, below; search
* this file for "Keyword category lists".
*/
/* ordinary key words in alphabetical order */
{{{ KEYWORDS }}}
/*
* The grammar thinks these are keywords, but they are not in the kwlist.h
* list and so can never be entered directly. The filter in parser.c
* creates these tokens when required (based on looking one token ahead).
*
* NOT_LA exists so that productions such as NOT LIKE can be given the same
* precedence as LIKE; otherwise they'd effectively have the same precedence
* as NOT, at least with respect to their left-hand subexpression.
* NULLS_LA and WITH_LA are needed to make the grammar LALR(1).
*/
%token NOT_LA NULLS_LA WITH_LA
/* Precedence: lowest to highest */
%left SINGLE_COLON
%nonassoc SET /* see */
%left UNION EXCEPT
%left INTERSECT
%left SINGLE_ARROW DOUBLE_ARROW
%left OR
%left AND
%right NOT
%nonassoc IS ISNULL NOTNULL /* IS sets precedence for IS NULL, etc */
%nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS
%nonassoc BETWEEN IN_P GLOB LIKE ILIKE SIMILAR NOT_LA
%nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */
%left POSTFIXOP /* dummy for postfix Op rules */
/*
* To support target_el without AS, we must give IDENT an explicit priority
* between POSTFIXOP and Op. We can safely assign the same priority to
* various unreserved keywords as needed to resolve ambiguities (this can't
* have any bad effects since obviously the keywords will still behave the
* same as if they weren't keywords). We need to do this for PARTITION,
* RANGE, ROWS to support opt_existing_window_name; and for RANGE, ROWS
* so that they can follow a_expr without creating postfix-operator problems;
* for GENERATED so that it can follow b_expr;
* and for NULL so that it can follow b_expr in without creating
* postfix-operator problems.
*
* To support CUBE and ROLLUP in GROUP BY without reserving them, we give them
* an explicit priority lower than '(', so that a rule with CUBE '(' will shift
* rather than reducing a conflicting rule that takes CUBE as a function name.
* Using the same precedence as IDENT seems right for the reasons given above.
*
* The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
* are even messier: since UNBOUNDED is an unreserved keyword (per spec!),
* there is no principled way to distinguish these from the productions
* a_expr PRECEDING/FOLLOWING. We hack this up by giving UNBOUNDED slightly
* lower precedence than PRECEDING and FOLLOWING. At present this doesn't
* appear to cause UNBOUNDED to be treated differently from other unreserved
* keywords anywhere else in the grammar, but it's definitely risky. We can
* blame any funny behavior of UNBOUNDED on the SQL standard, though.
*/
%nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */
%nonassoc IDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP ENUM_P
%left Op OPERATOR /* multi-character ops and user-defined operators */
%left '+' '-'
%left '*' '/' '%' INTEGER_DIVISION
%left '^' POWER_OF
/* Unary Operators */
%left AT /* sets precedence for AT TIME ZONE */
%left COLLATE
%right UMINUS
%left '[' ']'
%left '(' ')'
%left TYPECAST
%left '.'
/*
* These might seem to be low-precedence, but actually they are not part
* of the arithmetic hierarchy at all in their use as JOIN operators.
* We make them high-precedence to support their use as function names.
* They wouldn't be given a precedence at all, were it not that we need
* left-associativity among the JOIN rules themselves.
*/
%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL POSITIONAL PIVOT UNPIVOT ANTI SEMI ASOF
/* kluge to keep from causing shift/reduce conflicts */
%right PRESERVE STRIP_P IGNORE_P RESPECT_P
%%
/*
* The target production for the whole parse.
*/
stmtblock: stmtmulti
{
pg_yyget_extra(yyscanner)->parsetree = $1;
}
;
/*
* At top level, we wrap each stmt with a PGRawStmt node carrying start location
* and length of the stmt's text. Notice that the start loc/len are driven
* entirely from semicolon locations (@2). It would seem natural to use
* @1 or @3 to get the true start location of a stmt, but that doesn't work
* for statements that can start with empty nonterminals (opt_with_clause is
* the main offender here); as noted in the comments for YYLLOC_DEFAULT,
* we'd get -1 for the location in such cases.
* We also take care to discard empty statements entirely.
*/
stmtmulti: stmtmulti ';' stmt
{
if ($1 != NIL)
{
/* update length of previous stmt */
updateRawStmtEnd(llast_node(PGRawStmt, $1), @2);
}
if ($3 != NULL)
$$ = lappend($1, makeRawStmt($3, @2 + 1));
else
$$ = $1;
}
| stmt
{
if ($1 != NULL)
$$ = list_make1(makeRawStmt($1, 0));
else
$$ = NIL;
}
;
{{{ STATEMENTS }}}
{{{ GRAMMAR RULES }}}
{{{ KEYWORD_DEFINITIONS }}}
%%
{{{ GRAMMAR_SOURCE }}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
BETWEEN
BIGINT
BIT
BOOLEAN_P
CHAR_P
CHARACTER
COALESCE
COLUMNS
DEC
DECIMAL_P
EXISTS
EXTRACT
FLOAT_P
GENERATED
GROUPING
GROUPING_ID
INOUT
INT_P
INTEGER
INTERVAL
MAP
NATIONAL
NCHAR
NONE
NULLIF
NUMERIC
OUT_P
OVERLAY
POSITION
PRECISION
REAL
ROW
SETOF
SMALLINT
SUBSTRING
STRUCT
TIME
TIMESTAMP
TREAT
TRIM
TRY_CAST
VALUES
VARCHAR
XMLATTRIBUTES
XMLCONCAT
XMLELEMENT
XMLEXISTS
XMLFOREST
XMLNAMESPACES
XMLPARSE
XMLPI
XMLROOT
XMLSERIALIZE
XMLTABLE

View File

@@ -0,0 +1,29 @@
ASOF
AT
AUTHORIZATION
BINARY
COLLATION
CONCURRENTLY
CROSS
FREEZE
FULL
GENERATED
GLOB
ILIKE
INNER_P
IS
ISNULL
JOIN
LEFT
LIKE
MAP
NATURAL
NOTNULL
OUTER_P
OVERLAPS
POSITIONAL
RIGHT
SIMILAR
STRUCT
TABLESAMPLE
VERBOSE

View File

@@ -0,0 +1,75 @@
ALL
ANALYSE
ANALYZE
AND
ANY
ARRAY
AS
ASC_P
ASYMMETRIC
BOTH
CASE
CAST
CHECK_P
COLLATE
COLUMN
CONSTRAINT
CREATE_P
DEFAULT
DEFERRABLE
DESC_P
DESCRIBE
DISTINCT
DO
ELSE
END_P
EXCEPT
FALSE_P
FETCH
FOR
FOREIGN
FROM
GROUP_P
HAVING
QUALIFY
IN_P
INITIALLY
INTERSECT
INTO
LAMBDA
LATERAL_P
LEADING
LIMIT
NOT
NULL_P
OFFSET
ON
ONLY
OR
ORDER
PIVOT
PIVOT_WIDER
PIVOT_LONGER
PLACING
PRIMARY
REFERENCES
RETURNING
SELECT
SHOW
SOME
SUMMARIZE
SYMMETRIC
TABLE
THEN
TO
TRAILING
TRUE_P
UNION
UNIQUE
UNPIVOT
USING
VARIADIC
WHEN
WHERE
WINDOW
WITH

View File

@@ -0,0 +1,32 @@
ASOF
AT
AUTHORIZATION
BINARY
BY
COLLATION
COLUMNS
CONCURRENTLY
CROSS
FREEZE
FULL
GLOB
ILIKE
INNER_P
IS
ISNULL
JOIN
LEFT
LIKE
NATURAL
NOTNULL
OUTER_P
OVERLAPS
POSITIONAL
RIGHT
UNPACK
SIMILAR
TABLESAMPLE
TRY_CAST
VERBOSE
SEMI
ANTI

View File

@@ -0,0 +1,330 @@
ABORT_P
ABSOLUTE_P
ACCESS
ACTION
ADD_P
ADMIN
AFTER
AGGREGATE
ALSO
ALTER
ALWAYS
ASSERTION
ASSIGNMENT
ATTACH
ATTRIBUTE
BACKWARD
BEFORE
BEGIN_P
CACHE
CALL_P
CALLED
CASCADE
CASCADED
CATALOG_P
CENTURY_P
CENTURIES_P
CHAIN
CHARACTERISTICS
CHECKPOINT
CLASS
CLOSE
CLUSTER
COMMENT
COMMENTS
COMMIT
COMMITTED
COMPRESSION
CONFIGURATION
CONFLICT
CONNECTION
CONSTRAINTS
CONTENT_P
CONTINUE_P
CONVERSION_P
COPY
COST
CSV
CUBE
CURRENT_P
CURSOR
CYCLE
DATA_P
DATABASE
DAY_P
DAYS_P
DEALLOCATE
DECADE_P
DECADES_P
DECLARE
DEFAULTS
DEFERRED
DEFINER
DELETE_P
DELIMITER
DELIMITERS
DEPENDS
DETACH
DICTIONARY
DISABLE_P
DISCARD
DOCUMENT_P
DOMAIN_P
DOUBLE_P
DROP
EACH
ENABLE_P
ENCODING
ENCRYPTED
ENUM_P
ERROR_P
ESCAPE
EVENT
EXCLUDE
EXCLUDING
EXCLUSIVE
EXECUTE
EXPLAIN
EXPORT_P
EXPORT_STATE
EXTENSION
EXTENSIONS
EXTERNAL
FAMILY
FILTER
FIRST_P
FOLLOWING
FORCE
FORWARD
FUNCTION
FUNCTIONS
GLOBAL
GRANT
GRANTED
GROUPS
HANDLER
HEADER_P
HOLD
HOUR_P
HOURS_P
IDENTITY_P
IF_P
IGNORE_P
IMMEDIATE
IMMUTABLE
IMPLICIT_P
IMPORT_P
INCLUDE_P
INCLUDING
INCREMENT
INDEX
INDEXES
INHERIT
INHERITS
INLINE_P
INPUT_P
INSENSITIVE
INSERT
INSTALL
INSTEAD
INVOKER
JSON
ISOLATION
KEY
LABEL
LANGUAGE
LARGE_P
LAST_P
LEAKPROOF
LEVEL
LISTEN
LOAD
LOCAL
LOCATION
LOCK_P
LOCKED
LOGGED
MACRO
MAPPING
MATCH
MATCHED
MATERIALIZED
MAXVALUE
MERGE
METHOD
MICROSECOND_P
MICROSECONDS_P
MILLENNIUM_P
MILLENNIA_P
MILLISECOND_P
MILLISECONDS_P
MINUTE_P
MINUTES_P
MINVALUE
MODE
MONTH_P
MONTHS_P
MOVE
NAME_P
NAMES
NEW
NEXT
NO
NOTHING
NOTIFY
NOWAIT
NULLS_P
OBJECT_P
OF
OFF
OIDS
OLD
OPERATOR
OPTION
OPTIONS
ORDINALITY
OTHERS
OVER
OVERRIDING
OWNED
OWNER
PARALLEL
PARSER
PARTIAL
PARTITION
PARTITIONED
PASSING
PASSWORD
PERCENT
PERSISTENT
PLANS
POLICY
PRAGMA_P
PRECEDING
PREPARE
PREPARED
PRESERVE
PRIOR
PRIVILEGES
PROCEDURAL
PROCEDURE
PROGRAM
PUBLICATION
QUARTER_P
QUARTERS_P
QUOTE
RANGE
READ_P
REASSIGN
RECHECK
RECURSIVE
REF
REFERENCING
REFRESH
REINDEX
RELATIVE_P
RELEASE
RENAME
REPEATABLE
REPLACE
REPLICA
RESET
RESPECT_P
RESTART
RESTRICT
RETURNS
REVOKE
ROLE
ROLLBACK
ROLLUP
ROWS
RULE
SAMPLE
SAVEPOINT
SCHEMA
SCHEMAS
SCOPE
SCROLL
SEARCH
SECRET
SECOND_P
SECONDS_P
SECURITY
SEQUENCE
SEQUENCES
SERIALIZABLE
SERVER
SESSION
SET
SETS
SHARE
SIMPLE
SKIP
SNAPSHOT
SORTED
SOURCE_P
SQL_P
STABLE
STANDALONE_P
START
STATEMENT
STATISTICS
STDIN
STDOUT
STORAGE
STORED
STRICT_P
STRIP_P
SUBSCRIPTION
SYSID
SYSTEM_P
TABLES
TABLESPACE
TARGET_P
TEMP
TEMPLATE
TEMPORARY
TEXT_P
TIES
TRANSACTION
TRANSFORM
TRIGGER
TRUNCATE
TRUSTED
TYPE_P
TYPES_P
UNBOUNDED
UNCOMMITTED
UNENCRYPTED
UNKNOWN
UNLISTEN
UNLOGGED
UNTIL
UPDATE
USE_P
USER
VACUUM
VALID
VALIDATE
VALIDATOR
VALUE_P
VARIABLE_P
VARYING
VERSION_P
VIEW
VIEWS
VIRTUAL
VOLATILE
WEEK_P
WEEKS_P
WHITESPACE_P
WITHIN
WITHOUT
WORK
WRAPPER
WRITE_P
XML_P
YEAR_P
YEARS_P
YES_P
ZONE

View File

@@ -0,0 +1,43 @@
AlterDatabaseStmt
AlterObjectSchemaStmt
AlterSeqStmt
AlterTableStmt
AnalyzeStmt
AttachStmt
CallStmt
CheckPointStmt
CopyStmt
CreateAsStmt
CreateSecretStmt
CreateTypeStmt
CreateFunctionStmt
CreateSchemaStmt
CreateSeqStmt
CreateStmt
CommentOnStmt
DeallocateStmt
DeleteStmt
DetachStmt
DropSecretStmt
DropStmt
ExecuteStmt
ExplainStmt
ExportStmt
ImportStmt
IndexStmt
InsertStmt
LoadStmt
MergeIntoStmt
PragmaStmt
PrepareStmt
RenameStmt
SelectStmt
TransactionStmt
UpdateStmt
UpdateExtensionsStmt
UseStmt
VacuumStmt
VariableResetStmt
VariableSetStmt
VariableShowStmt
ViewStmt

View File

@@ -0,0 +1,25 @@
/*****************************************************************************
*
* Alter Database Statement
*
*****************************************************************************/
AlterDatabaseStmt:
ALTER DATABASE ColId RENAME TO ColId
{
PGAlterDatabaseStmt *n = makeNode(PGAlterDatabaseStmt);
n->dbname = $3;
n->new_name = $6;
n->alter_type = PG_ALTER_DATABASE_RENAME;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER DATABASE IF_P EXISTS ColId RENAME TO ColId
{
PGAlterDatabaseStmt *n = makeNode(PGAlterDatabaseStmt);
n->dbname = $5;
n->new_name = $8;
n->alter_type = PG_ALTER_DATABASE_RENAME;
n->missing_ok = true;
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,61 @@
/*****************************************************************************
*
* ALTER THING name SET SCHEMA name
*
*****************************************************************************/
AlterObjectSchemaStmt:
ALTER TABLE relation_expr SET SCHEMA name
{
PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
n->objectType = PG_OBJECT_TABLE;
n->relation = $3;
n->newschema = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER TABLE IF_P EXISTS relation_expr SET SCHEMA name
{
PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
n->objectType = PG_OBJECT_TABLE;
n->relation = $5;
n->newschema = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE qualified_name SET SCHEMA name
{
PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
n->objectType = PG_OBJECT_SEQUENCE;
n->relation = $3;
n->newschema = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE IF_P EXISTS qualified_name SET SCHEMA name
{
PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
n->objectType = PG_OBJECT_SEQUENCE;
n->relation = $5;
n->newschema = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER VIEW qualified_name SET SCHEMA name
{
PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
n->objectType = PG_OBJECT_VIEW;
n->relation = $3;
n->newschema = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER VIEW IF_P EXISTS qualified_name SET SCHEMA name
{
PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt);
n->objectType = PG_OBJECT_VIEW;
n->relation = $5;
n->newschema = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,120 @@
/*****************************************************************************
*
* QUERY :
* CREATE SEQUENCE seqname
* ALTER SEQUENCE seqname
*
*****************************************************************************/
AlterSeqStmt:
ALTER SEQUENCE qualified_name SeqOptList
{
PGAlterSeqStmt *n = makeNode(PGAlterSeqStmt);
n->sequence = $3;
n->options = $4;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE IF_P EXISTS qualified_name SeqOptList
{
PGAlterSeqStmt *n = makeNode(PGAlterSeqStmt);
n->sequence = $5;
n->options = $6;
n->missing_ok = true;
$$ = (PGNode *)n;
}
;
SeqOptList: SeqOptElem { $$ = list_make1($1); }
| SeqOptList SeqOptElem { $$ = lappend($1, $2); }
;
opt_with: WITH {}
| WITH_LA {}
| /*EMPTY*/ {}
;
NumericOnly:
FCONST { $$ = makeFloat($1); }
| '+' FCONST { $$ = makeFloat($2); }
| '-' FCONST
{
$$ = makeFloat($2);
doNegateFloat($$);
}
| SignedIconst { $$ = makeInteger($1); }
;
SeqOptElem: AS SimpleTypename
{
$$ = makeDefElem("as", (PGNode *)$2, @1);
}
| CACHE NumericOnly
{
$$ = makeDefElem("cache", (PGNode *)$2, @1);
}
| CYCLE
{
$$ = makeDefElem("cycle", (PGNode *)makeInteger(true), @1);
}
| NO CYCLE
{
$$ = makeDefElem("cycle", (PGNode *)makeInteger(false), @1);
}
| INCREMENT opt_by NumericOnly
{
$$ = makeDefElem("increment", (PGNode *)$3, @1);
}
| MAXVALUE NumericOnly
{
$$ = makeDefElem("maxvalue", (PGNode *)$2, @1);
}
| MINVALUE NumericOnly
{
$$ = makeDefElem("minvalue", (PGNode *)$2, @1);
}
| NO MAXVALUE
{
$$ = makeDefElem("maxvalue", NULL, @1);
}
| NO MINVALUE
{
$$ = makeDefElem("minvalue", NULL, @1);
}
| OWNED BY any_name
{
$$ = makeDefElem("owned_by", (PGNode *)$3, @1);
}
| SEQUENCE NAME_P any_name
{
/* not documented, only used by pg_dump */
$$ = makeDefElem("sequence_name", (PGNode *)$3, @1);
}
| START opt_with NumericOnly
{
$$ = makeDefElem("start", (PGNode *)$3, @1);
}
| RESTART
{
$$ = makeDefElem("restart", NULL, @1);
}
| RESTART opt_with NumericOnly
{
$$ = makeDefElem("restart", (PGNode *)$3, @1);
}
;
opt_by: BY {}
| /* empty */ {}
;
SignedIconst: Iconst { $$ = $1; }
| '+' Iconst { $$ = + $2; }
| '-' Iconst { $$ = - $2; }
;

View File

@@ -0,0 +1,525 @@
/*****************************************************************************
*
* ALTER [ TABLE | INDEX | SEQUENCE | VIEW | MATERIALIZED VIEW ] variations
*
* Note: we accept all subcommands for each of the five variants, and sort
* out what's really legal at execution time.
*****************************************************************************/
AlterTableStmt:
ALTER TABLE relation_expr alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $3;
n->cmds = $4;
n->relkind = PG_OBJECT_TABLE;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER TABLE IF_P EXISTS relation_expr alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $5;
n->cmds = $6;
n->relkind = PG_OBJECT_TABLE;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER INDEX qualified_name alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $3;
n->cmds = $4;
n->relkind = PG_OBJECT_INDEX;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER INDEX IF_P EXISTS qualified_name alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $5;
n->cmds = $6;
n->relkind = PG_OBJECT_INDEX;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE qualified_name alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $3;
n->cmds = $4;
n->relkind = PG_OBJECT_SEQUENCE;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE IF_P EXISTS qualified_name alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $5;
n->cmds = $6;
n->relkind = PG_OBJECT_SEQUENCE;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER VIEW qualified_name alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $3;
n->cmds = $4;
n->relkind = PG_OBJECT_VIEW;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER VIEW IF_P EXISTS qualified_name alter_table_cmds
{
PGAlterTableStmt *n = makeNode(PGAlterTableStmt);
n->relation = $5;
n->cmds = $6;
n->relkind = PG_OBJECT_VIEW;
n->missing_ok = true;
$$ = (PGNode *)n;
}
;
alter_identity_column_option_list:
alter_identity_column_option
{ $$ = list_make1($1); }
| alter_identity_column_option_list alter_identity_column_option
{ $$ = lappend($1, $2); }
;
alter_column_default:
SET DEFAULT a_expr { $$ = $3; }
| DROP DEFAULT { $$ = NULL; }
;
alter_identity_column_option:
RESTART
{
$$ = makeDefElem("restart", NULL, @1);
}
| RESTART opt_with NumericOnly
{
$$ = makeDefElem("restart", (PGNode *)$3, @1);
}
| SET SeqOptElem
{
if (strcmp($2->defname, "as") == 0 ||
strcmp($2->defname, "restart") == 0 ||
strcmp($2->defname, "owned_by") == 0)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("sequence option \"%s\" not supported here", $2->defname),
parser_errposition(@2)));
$$ = $2;
}
| SET GENERATED generated_when
{
$$ = makeDefElem("generated", (PGNode *) makeInteger($3), @1);
}
;
alter_generic_option_list:
alter_generic_option_elem
{
$$ = list_make1($1);
}
| alter_generic_option_list ',' alter_generic_option_elem
{
$$ = lappend($1, $3);
}
;
qualify_list:
qualify_el { $$ = list_make1($1); }
| qualify_list qualify_el { $$ = lappend($1, $2); }
;
qualify_el:
'.' attr_name
{
$$ = $2;
}
;
qualified_column:
ColId { $$ = list_make1($1); }
| ColId qualify_list { $$ = list_concat(list_make1($1), $2); }
;
qualifiedColumnDef:
qualified_column regularColumnDef
{
PGColumnDef *n = (PGColumnDef *) $2;
n->location = @1;
$$ = list_make2($1, n);
}
|
qualified_column generatedColumnDef
{
PGColumnDef *n = (PGColumnDef *) $2;
n->location = @1;
$$ = list_make2($1, n);
}
;
alter_table_cmd:
/* ALTER TABLE <name> ADD <coldef> */
ADD_P qualifiedColumnDef
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_AddColumn;
n->def_list = $2;
n->missing_ok = false;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ADD IF NOT EXISTS <coldef> */
| ADD_P IF_P NOT EXISTS qualifiedColumnDef
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_AddColumn;
n->def_list = $5;
n->missing_ok = true;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ADD COLUMN <coldef> */
| ADD_P COLUMN qualifiedColumnDef
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_AddColumn;
n->def_list = $3;
n->missing_ok = false;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ADD COLUMN IF NOT EXISTS <coldef> */
| ADD_P COLUMN IF_P NOT EXISTS qualifiedColumnDef
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_AddColumn;
n->def_list = $6;
n->missing_ok = true;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> SET PARTITIONED BY ( <partition_key_list> ) */
| SET PARTITIONED BY '(' expr_list_opt_comma ')'
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetPartitionedBy;
n->def_list = $5;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> RESET PARTITIONED BY */
| RESET PARTITIONED BY
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetPartitionedBy;
n->def_list = NULL;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> SET SORTED BY ( <order_key_list> ) */
| SET SORTED BY '(' sortby_list ')'
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetSortedBy;
n->def_list = $5;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> RESET SORTED BY */
| RESET SORTED BY
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetSortedBy;
n->def_list = NULL;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
| ALTER opt_column ColId alter_column_default
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_ColumnDefault;
n->name = $3;
n->def = $4;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP NOT NULL */
| ALTER opt_column ColId DROP NOT NULL_P
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_DropNotNull;
n->name = $3;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET NOT NULL */
| ALTER opt_column ColId SET NOT NULL_P
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetNotNull;
n->name = $3;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS <SignedIconst> */
| ALTER opt_column ColId SET STATISTICS SignedIconst
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetStatistics;
n->name = $3;
n->def = (PGNode *) makeInteger($6);
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */
| ALTER opt_column ColId SET reloptions
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetOptions;
n->name = $3;
n->def = (PGNode *) $5;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> RESET ( column_parameter = value [, ... ] ) */
| ALTER opt_column ColId RESET reloptions
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_ResetOptions;
n->name = $3;
n->def = (PGNode *) $5;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
| ALTER opt_column ColId SET STORAGE ColId
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetStorage;
n->name = $3;
n->def = (PGNode *) makeString($6);
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED ... AS IDENTITY ... */
| ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
PGConstraint *c = makeNode(PGConstraint);
c->contype = PG_CONSTR_IDENTITY;
c->generated_when = $6;
c->options = $9;
c->location = @5;
n->subtype = PG_AT_AddIdentity;
n->name = $3;
n->def = (PGNode *) c;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET <sequence options>/RESET */
| ALTER opt_column ColId alter_identity_column_option_list
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetIdentity;
n->name = $3;
n->def = (PGNode *) $4;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY */
| ALTER opt_column ColId DROP IDENTITY_P
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = AT_DropIdentity;
n->name = $3;
n->missing_ok = false;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY IF EXISTS */
| ALTER opt_column ColId DROP IDENTITY_P IF_P EXISTS
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = AT_DropIdentity;
n->name = $3;
n->missing_ok = true;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> DROP [COLUMN] IF EXISTS <colname> [RESTRICT|CASCADE] */
| DROP opt_column IF_P EXISTS qualified_column opt_drop_behavior
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_DropColumn;
n->def_list = $5;
n->behavior = $6;
n->missing_ok = true;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> DROP [COLUMN] <colname> [RESTRICT|CASCADE] */
| DROP opt_column qualified_column opt_drop_behavior
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_DropColumn;
n->def_list = $3;
n->behavior = $4;
n->missing_ok = false;
$$ = (PGNode *)n;
}
/*
* ALTER TABLE <name> ALTER [COLUMN] <colname> [SET DATA] TYPE <typename>
* [ USING <expression> ] [RESTRICT|CASCADE]
*/
| ALTER opt_column ColId opt_set_data TYPE_P opt_Typename opt_collate_clause alter_using
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
PGColumnDef *def = makeNode(PGColumnDef);
n->subtype = PG_AT_AlterColumnType;
n->name = $3;
n->def = (PGNode *) def;
/* We only use these fields of the PGColumnDef node */
def->typeName = $6;
def->collClause = (PGCollateClause *) $7;
def->raw_default = $8;
def->location = @3;
$$ = (PGNode *)n;
}
/* ALTER FOREIGN TABLE <name> ALTER [COLUMN] <colname> OPTIONS */
| ALTER opt_column ColId alter_generic_options
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_AlterColumnGenericOptions;
n->name = $3;
n->def = (PGNode *) $4;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ADD CONSTRAINT ... */
| ADD_P TableConstraint
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_AddConstraint;
n->def = $2;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> ALTER CONSTRAINT ... */
| ALTER CONSTRAINT name ConstraintAttributeSpec
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
PGConstraint *c = makeNode(PGConstraint);
n->subtype = PG_AT_AlterConstraint;
n->def = (PGNode *) c;
c->contype = PG_CONSTR_FOREIGN; /* others not supported, yet */
c->conname = $3;
processCASbits($4, @4, "ALTER CONSTRAINT statement",
&c->deferrable,
&c->initdeferred,
NULL, NULL, yyscanner);
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> VALIDATE CONSTRAINT ... */
| VALIDATE CONSTRAINT name
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_ValidateConstraint;
n->name = $3;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> DROP CONSTRAINT IF EXISTS <name> [RESTRICT|CASCADE] */
| DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_DropConstraint;
n->name = $5;
n->behavior = $6;
n->missing_ok = true;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> DROP CONSTRAINT <name> [RESTRICT|CASCADE] */
| DROP CONSTRAINT name opt_drop_behavior
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_DropConstraint;
n->name = $3;
n->behavior = $4;
n->missing_ok = false;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> SET LOGGED */
| SET LOGGED
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetLogged;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> SET UNLOGGED */
| SET UNLOGGED
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetUnLogged;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> SET (...) */
| SET reloptions
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_SetRelOptions;
n->def = (PGNode *)$2;
$$ = (PGNode *)n;
}
/* ALTER TABLE <name> RESET (...) */
| RESET reloptions
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_ResetRelOptions;
n->def = (PGNode *)$2;
$$ = (PGNode *)n;
}
| alter_generic_options
{
PGAlterTableCmd *n = makeNode(PGAlterTableCmd);
n->subtype = PG_AT_GenericOptions;
n->def = (PGNode *)$1;
$$ = (PGNode *) n;
}
;
alter_using:
USING a_expr { $$ = $2; }
| /* EMPTY */ { $$ = NULL; }
;
alter_generic_option_elem:
generic_option_elem
{
$$ = $1;
}
| SET generic_option_elem
{
$$ = $2;
$$->defaction = PG_DEFELEM_SET;
}
| ADD_P generic_option_elem
{
$$ = $2;
$$->defaction = PG_DEFELEM_ADD;
}
| DROP generic_option_name
{
$$ = makeDefElemExtended(NULL, $2, NULL, DEFELEM_DROP, @2);
}
;
alter_table_cmds:
alter_table_cmd { $$ = list_make1($1); }
| alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); }
;
alter_generic_options:
OPTIONS '(' alter_generic_option_list ')' { $$ = $3; }
;
opt_set_data: SET DATA_P { $$ = 1; }
| SET { $$ = 0; }
| /*EMPTY*/ { $$ = 0; }
;

View File

@@ -0,0 +1,29 @@
/*****************************************************************************
*
* QUERY:
* VACUUM
* ANALYZE
*
*****************************************************************************/
AnalyzeStmt:
analyze_keyword opt_verbose
{
PGVacuumStmt *n = makeNode(PGVacuumStmt);
n->options = PG_VACOPT_ANALYZE;
if ($2)
n->options |= PG_VACOPT_VERBOSE;
n->relation = NULL;
n->va_cols = NIL;
$$ = (PGNode *)n;
}
| analyze_keyword opt_verbose qualified_name opt_name_list
{
PGVacuumStmt *n = makeNode(PGVacuumStmt);
n->options = PG_VACOPT_ANALYZE;
if ($2)
n->options |= PG_VACOPT_VERBOSE;
n->relation = $3;
n->va_cols = $4;
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,108 @@
/*****************************************************************************
*
* Attach Statement
*
*****************************************************************************/
AttachStmt:
ATTACH opt_database Sconst opt_database_alias opt_attach_options
{
PGAttachStmt *n = makeNode(PGAttachStmt);
n->path = $3;
n->name = $4;
n->options = $5;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| ATTACH IF_P NOT EXISTS opt_database Sconst opt_database_alias opt_attach_options
{
PGAttachStmt *n = makeNode(PGAttachStmt);
n->path = $6;
n->name = $7;
n->options = $8;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| ATTACH OR REPLACE opt_database Sconst opt_database_alias opt_attach_options
{
PGAttachStmt *n = makeNode(PGAttachStmt);
n->path = $5;
n->name = $6;
n->options = $7;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
DetachStmt:
DETACH ColLabel
{
PGDetachStmt *n = makeNode(PGDetachStmt);
n->missing_ok = false;
n->db_name = $2;
$$ = (PGNode *)n;
}
| DETACH DATABASE ColLabel
{
PGDetachStmt *n = makeNode(PGDetachStmt);
n->missing_ok = false;
n->db_name = $3;
$$ = (PGNode *)n;
}
| DETACH DATABASE IF_P EXISTS ColLabel
{
PGDetachStmt *n = makeNode(PGDetachStmt);
n->missing_ok = true;
n->db_name = $5;
$$ = (PGNode *)n;
}
;
opt_database: DATABASE {}
| /*EMPTY*/ {}
;
opt_database_alias:
AS ColId { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
;
ident_name: IDENT { $$ = list_make1(makeString($1)); }
ident_list:
ident_name { $$ = list_make1($1); }
| ident_list ',' ident_name { $$ = lappend($1, $3); }
;
generic_opt_arg:
a_expr { $$ = (PGNode *) $1; }
| /* EMPTY */ { $$ = NULL; }
;
generic_opt_elem:
ColLabel generic_opt_arg
{
$$ = makeDefElem($1, $2, @1);
}
;
generic_opt_list:
generic_opt_elem
{
$$ = list_make1($1);
}
| generic_opt_list ',' generic_opt_elem
{
$$ = lappend($1, $3);
}
;
opt_attach_options:
'(' generic_opt_list ')'
{
$$ = $2;
}
| /* EMPTY */
{
$$ = NULL;
}
;

View File

@@ -0,0 +1,12 @@
/*****************************************************************************
*
* CALL <proc_name> [(params, ...)]
*
*****************************************************************************/
CallStmt: CALL_P func_application
{
PGCallStmt *n = makeNode(PGCallStmt);
n->func = $2;
$$ = (PGNode *) n;
}
;

View File

@@ -0,0 +1,23 @@
/*
* Checkpoint statement
*/
CheckPointStmt:
FORCE CHECKPOINT opt_col_id
{
PGCheckPointStmt *n = makeNode(PGCheckPointStmt);
n->force = true;
n->name = $3;
$$ = (PGNode *)n;
}
| CHECKPOINT opt_col_id
{
PGCheckPointStmt *n = makeNode(PGCheckPointStmt);
n->force = false;
n->name = $2;
$$ = (PGNode *)n;
}
;
opt_col_id:
ColId { $$ = $1; }
| /* empty */ { $$ = NULL; }

View File

@@ -0,0 +1,40 @@
/*****************************************************************************
*
* Create a Comment
*
*****************************************************************************/
CommentOnStmt:
COMMENT ON comment_on_type_any_name qualified_name IS comment_value
{
PGCommentOnStmt *n = makeNode(PGCommentOnStmt);
n->object_type = $3;
n->name = $4;
n->value = $6;
$$ = (PGNode *)n;
}
| COMMENT ON COLUMN a_expr IS comment_value
{
PGCommentOnStmt *n = makeNode(PGCommentOnStmt);
n->object_type = PG_OBJECT_COLUMN;
n->column_expr = $4;
n->value = $6;
$$ = (PGNode *)n;
}
;
comment_value:
Sconst { $$ = makeStringConst($1, @1); }
| NULL_P { $$ = makeNullAConst(@1); }
comment_on_type_any_name:
TABLE { $$ = PG_OBJECT_TABLE; }
| SEQUENCE { $$ = PG_OBJECT_SEQUENCE; }
| FUNCTION { $$ = PG_OBJECT_FUNCTION; }
| MACRO { $$ = PG_OBJECT_FUNCTION; }
| MACRO TABLE { $$ = PG_OBJECT_TABLE_MACRO; }
| VIEW { $$ = PG_OBJECT_VIEW; }
| DATABASE { $$ = PG_OBJECT_DATABASE; }
| INDEX { $$ = PG_OBJECT_INDEX; }
| SCHEMA { $$ = PG_OBJECT_SCHEMA; }
| TYPE_P { $$ = PG_OBJECT_TYPE; }
;

View File

@@ -0,0 +1,80 @@
/*
* The production for a qualified relation name has to exactly match the
* production for a qualified func_name, because in a FROM clause we cannot
* tell which we are parsing until we see what comes after it ('(' for a
* func_name, something else for a relation). Therefore we allow 'indirection'
* which may contain subscripts, and reject that case in the C code.
*/
qualified_name:
ColIdOrString
{
$$ = makeRangeVar(NULL, $1, @1);
}
| ColId indirection
{
check_qualified_name($2, yyscanner);
$$ = makeRangeVar(NULL, NULL, @1);
switch (list_length($2))
{
case 1:
$$->catalogname = NULL;
$$->schemaname = $1;
$$->relname = strVal(linitial($2));
break;
case 2:
$$->catalogname = $1;
$$->schemaname = strVal(linitial($2));
$$->relname = strVal(lsecond($2));
break;
case 3:
default:
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
NameListToString(lcons(makeString($1), $2))),
parser_errposition(@1)));
break;
}
}
;
/* Column identifier --- names that can be column, table, etc names.
*/
ColId: IDENT { $$ = $1; }
| unreserved_keyword { $$ = pstrdup($1); }
| col_name_keyword { $$ = pstrdup($1); }
;
ColIdOrString: ColId { $$ = $1; }
| SCONST { $$ = $1; }
;
Sconst: SCONST { $$ = $1; };
indirection:
indirection_el { $$ = list_make1($1); }
| indirection indirection_el { $$ = lappend($1, $2); }
;
indirection_el:
'.' attr_name
{
$$ = (PGNode *) makeString($2);
}
;
attr_name: ColLabel { $$ = $1; };
/* Column label --- allowed labels in "AS" clauses.
* This presently includes *all* Postgres keywords.
*/
ColLabel: IDENT { $$ = $1; }
| other_keyword { $$ = pstrdup($1); }
| unreserved_keyword { $$ = pstrdup($1); }
| reserved_keyword { $$ = pstrdup($1); }
;

View File

@@ -0,0 +1,218 @@
CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids
copy_from opt_program copy_file_name copy_delimiter opt_with copy_options
{
PGCopyStmt *n = makeNode(PGCopyStmt);
n->relation = $3;
n->query = NULL;
n->attlist = $4;
n->is_from = $6;
n->is_program = $7;
n->filename = $8;
if (n->is_program && n->filename == NULL)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("STDIN/STDOUT not allowed with PROGRAM"),
parser_errposition(@8)));
n->options = NIL;
/* Concatenate user-supplied flags */
if ($2)
n->options = lappend(n->options, $2);
if ($5)
n->options = lappend(n->options, $5);
if ($9)
n->options = lappend(n->options, $9);
if ($11)
n->options = list_concat(n->options, $11);
$$ = (PGNode *)n;
}
| COPY '(' SelectStmt ')' TO opt_program copy_file_name opt_with copy_options
{
PGCopyStmt *n = makeNode(PGCopyStmt);
n->relation = NULL;
n->query = $3;
n->attlist = NIL;
n->is_from = false;
n->is_program = $6;
n->filename = $7;
n->options = $9;
if (n->is_program && n->filename == NULL)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("STDIN/STDOUT not allowed with PROGRAM"),
parser_errposition(@5)));
$$ = (PGNode *)n;
}
| COPY FROM DATABASE ColId TO ColId copy_database_flag
{
PGCopyDatabaseStmt *n = makeNode(PGCopyDatabaseStmt);
n->from_database = $4;
n->to_database = $6;
n->copy_database_flag = $7;
$$ = (PGNode *)n;
}
;
copy_database_flag:
/* empty */ { $$ = NULL; }
| '(' SCHEMA ')' { $$ = "schema"; }
| '(' DATA_P ')' { $$ = "data"; }
;
copy_from:
FROM { $$ = true; }
| TO { $$ = false; }
;
copy_delimiter:
opt_using DELIMITERS Sconst
{
$$ = makeDefElem("delimiter", (PGNode *)makeString($3), @2);
}
| /*EMPTY*/ { $$ = NULL; }
;
copy_generic_opt_arg_list:
copy_generic_opt_arg_list_item
{
$$ = list_make1($1);
}
| copy_generic_opt_arg_list ',' copy_generic_opt_arg_list_item
{
$$ = lappend($1, $3);
}
;
opt_using:
USING {}
| /*EMPTY*/ {}
;
opt_as: AS {}
| /* EMPTY */ {}
;
opt_program:
PROGRAM { $$ = true; }
| /* EMPTY */ { $$ = false; }
;
copy_options: copy_opt_list { $$ = $1; }
| '(' generic_opt_list ')' { $$ = $2; }
;
opt_oids:
WITH OIDS
{
$$ = makeDefElem("oids", NULL, @1);
}
| /*EMPTY*/ { $$ = NULL; }
;
copy_opt_list:
copy_opt_list copy_opt_item { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NIL; }
;
opt_binary:
BINARY
{
$$ = makeDefElem("format", (PGNode *)makeStringConst("binary", @1), @1);
}
| /*EMPTY*/ { $$ = NULL; }
;
copy_opt_item:
BINARY
{
$$ = makeDefElem("format", (PGNode *)makeStringConst("binary", @1), @1);
}
| OIDS
{
$$ = makeDefElem("oids", NULL, @1);
}
| FREEZE
{
$$ = makeDefElem("freeze", NULL, @1);
}
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (PGNode *)makeStringConst($3, @3), @1);
}
| NULL_P opt_as Sconst
{
$$ = makeDefElem("null", (PGNode *)makeStringConst($3, @3), @1);
}
| CSV
{
$$ = makeDefElem("format", (PGNode *)makeStringConst("csv", @1), @1);
}
| HEADER_P
{
$$ = makeDefElem("header", NULL, @1);
}
| QUOTE opt_as Sconst
{
$$ = makeDefElem("quote", (PGNode *)makeStringConst($3, @3), @1);
}
| ESCAPE opt_as Sconst
{
$$ = makeDefElem("escape", (PGNode *)makeStringConst($3, @3), @1);
}
| FORCE QUOTE columnList
{
$$ = makeDefElem("force_quote", (PGNode *)$3, @1);
}
| FORCE QUOTE '*'
{
$$ = makeDefElem("force_quote", (PGNode *)makeNode(PGAStar), @1);
}
| PARTITION BY columnList
{
$$ = makeDefElem("partition_by", (PGNode *)$3, @1);
}
| PARTITION BY '*'
{
$$ = makeDefElem("partition_by", (PGNode *)makeNode(PGAStar), @1);
}
| FORCE NOT NULL_P columnList
{
$$ = makeDefElem("force_not_null", (PGNode *)$4, @1);
}
| FORCE NULL_P columnList
{
$$ = makeDefElem("force_null", (PGNode *)$3, @1);
}
| ENCODING Sconst
{
$$ = makeDefElem("encoding", (PGNode *)makeStringConst($2, @2), @1);
}
;
copy_generic_opt_arg_list_item:
opt_boolean_or_string { $$ = (PGNode *) makeString($1); }
;
copy_file_name:
Sconst { $$ = makeStringConst($1, @1); }
| STDIN { $$ = makeStringConst("/dev/stdin", @1); }
| STDOUT { $$ = makeStringConst("/dev/stdout", @1); }
| IDENT '.' ColId { $$ = makeStringConst(psprintf("%s.%s", $1, $3), @1); }
| IDENT { $$ = makeStringConst($1, @1); }
| '(' a_expr ')' { $$ = $2; }
| param_expr { $$ = $1; }
;

View File

@@ -0,0 +1,759 @@
/*****************************************************************************
*
* QUERY :
* CREATE TABLE relname
*
*****************************************************************************/
CreateStmt: CREATE_P OptTemp TABLE qualified_name '(' OptTableElementList ')'
OptWith OnCommitOption
{
PGCreateStmt *n = makeNode(PGCreateStmt);
$4->relpersistence = $2;
n->relation = $4;
n->tableElts = $6;
n->ofTypename = NULL;
n->constraints = NIL;
n->options = $8;
n->oncommit = $9;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OptTemp TABLE IF_P NOT EXISTS qualified_name '('
OptTableElementList ')' OptWith
OnCommitOption
{
PGCreateStmt *n = makeNode(PGCreateStmt);
$7->relpersistence = $2;
n->relation = $7;
n->tableElts = $9;
n->ofTypename = NULL;
n->constraints = NIL;
n->options = $11;
n->oncommit = $12;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE OptTemp TABLE qualified_name '('
OptTableElementList ')' OptWith
OnCommitOption
{
PGCreateStmt *n = makeNode(PGCreateStmt);
$6->relpersistence = $4;
n->relation = $6;
n->tableElts = $8;
n->ofTypename = NULL;
n->constraints = NIL;
n->options = $10;
n->oncommit = $11;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
ConstraintAttributeSpec:
/*EMPTY*/
{ $$ = 0; }
| ConstraintAttributeSpec ConstraintAttributeElem
{
/*
* We must complain about conflicting options.
* We could, but choose not to, complain about redundant
* options (ie, where $2's bit is already set in $1).
*/
int newspec = $1 | $2;
/* special message for this case */
if ((newspec & (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) == (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED))
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
parser_errposition(@2)));
/* generic message for other conflicts */
if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) ||
(newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED))
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("conflicting constraint properties"),
parser_errposition(@2)));
$$ = newspec;
}
;
def_arg: func_type { $$ = (PGNode *)$1; }
| reserved_keyword { $$ = (PGNode *)makeString(pstrdup($1)); }
| qual_all_Op { $$ = (PGNode *)$1; }
| NumericOnly { $$ = (PGNode *)$1; }
| Sconst { $$ = (PGNode *)makeString($1); }
| NONE { $$ = (PGNode *)makeString(pstrdup($1)); }
;
OptParenthesizedSeqOptList: '(' SeqOptList ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
generic_option_arg:
Sconst { $$ = (PGNode *) makeString($1); }
;
key_action:
NO ACTION { $$ = PG_FKCONSTR_ACTION_NOACTION; }
| RESTRICT { $$ = PG_FKCONSTR_ACTION_RESTRICT; }
| CASCADE { $$ = PG_FKCONSTR_ACTION_CASCADE; }
| SET NULL_P { $$ = PG_FKCONSTR_ACTION_SETNULL; }
| SET DEFAULT { $$ = PG_FKCONSTR_ACTION_SETDEFAULT; }
;
ColConstraint:
CONSTRAINT name ColConstraintElem
{
PGConstraint *n = castNode(PGConstraint, $3);
n->conname = $2;
n->location = @1;
$$ = (PGNode *) n;
}
| ColConstraintElem { $$ = $1; }
| ConstraintAttr { $$ = $1; }
| COLLATE any_name
{
/*
* Note: the PGCollateClause is momentarily included in
* the list built by ColQualList, but we split it out
* again in SplitColQualList.
*/
PGCollateClause *n = makeNode(PGCollateClause);
n->arg = NULL;
n->collname = $2;
n->location = @1;
$$ = (PGNode *) n;
}
;
ColConstraintElem:
NOT NULL_P
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_NOTNULL;
n->location = @1;
$$ = (PGNode *)n;
}
| NULL_P
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_NULL;
n->location = @1;
$$ = (PGNode *)n;
}
| UNIQUE opt_definition
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_UNIQUE;
n->location = @1;
n->keys = NULL;
n->options = $2;
n->indexname = NULL;
$$ = (PGNode *)n;
}
| PRIMARY KEY opt_definition
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_PRIMARY;
n->location = @1;
n->keys = NULL;
n->options = $3;
n->indexname = NULL;
$$ = (PGNode *)n;
}
| CHECK_P '(' a_expr ')' opt_no_inherit
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_CHECK;
n->location = @1;
n->is_no_inherit = $5;
n->raw_expr = $3;
n->cooked_expr = NULL;
n->skip_validation = false;
n->initially_valid = true;
$$ = (PGNode *)n;
}
| USING COMPRESSION name
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_COMPRESSION;
n->location = @1;
n->compression_name = $3;
$$ = (PGNode *)n;
}
| DEFAULT b_expr
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_DEFAULT;
n->location = @1;
n->raw_expr = $2;
n->cooked_expr = NULL;
$$ = (PGNode *)n;
}
| REFERENCES qualified_name opt_column_list key_match key_actions
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_FOREIGN;
n->location = @1;
n->pktable = $2;
n->fk_attrs = NIL;
n->pk_attrs = $3;
n->fk_matchtype = $4;
n->fk_upd_action = (char) ($5 >> 8);
n->fk_del_action = (char) ($5 & 0xFF);
n->skip_validation = false;
n->initially_valid = true;
$$ = (PGNode *)n;
}
;
GeneratedColumnType:
VIRTUAL { $$ = PG_CONSTR_GENERATED_VIRTUAL; }
| STORED { $$ = PG_CONSTR_GENERATED_STORED; }
;
opt_GeneratedColumnType:
GeneratedColumnType { $$ = $1; }
| /* EMPTY */ { $$ = PG_CONSTR_GENERATED_VIRTUAL; }
;
GeneratedConstraintElem:
GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_IDENTITY;
n->generated_when = $2;
n->options = $5;
n->location = @1;
$$ = (PGNode *)n;
}
| GENERATED generated_when AS '(' a_expr ')' opt_GeneratedColumnType
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = $7;
n->generated_when = $2;
n->raw_expr = $5;
n->cooked_expr = NULL;
n->location = @1;
/*
* Can't do this in the grammar because of shift/reduce
* conflicts. (IDENTITY allows both ALWAYS and BY
* DEFAULT, but generated columns only allow ALWAYS.) We
* can also give a more useful error message and location.
*/
if ($2 != PG_ATTRIBUTE_IDENTITY_ALWAYS)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("for a generated column, GENERATED ALWAYS must be specified"),
parser_errposition(@2)));
$$ = (PGNode *)n;
}
| AS '(' a_expr ')' opt_GeneratedColumnType
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = $5;
n->generated_when = PG_ATTRIBUTE_IDENTITY_ALWAYS;
n->raw_expr = $3;
n->cooked_expr = NULL;
n->location = @1;
$$ = (PGNode *)n;
}
;
generic_option_elem:
generic_option_name generic_option_arg
{
$$ = makeDefElem($1, $2, @1);
}
;
key_update: ON UPDATE key_action { $$ = $3; }
;
key_actions:
key_update
{ $$ = ($1 << 8) | (PG_FKCONSTR_ACTION_NOACTION & 0xFF); }
| key_delete
{ $$ = (PG_FKCONSTR_ACTION_NOACTION << 8) | ($1 & 0xFF); }
| key_update key_delete
{ $$ = ($1 << 8) | ($2 & 0xFF); }
| key_delete key_update
{ $$ = ($2 << 8) | ($1 & 0xFF); }
| /*EMPTY*/
{ $$ = (PG_FKCONSTR_ACTION_NOACTION << 8) | (PG_FKCONSTR_ACTION_NOACTION & 0xFF); }
;
OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
| ON COMMIT DELETE_P ROWS { $$ = PG_ONCOMMIT_DELETE_ROWS; }
| ON COMMIT PRESERVE ROWS { $$ = PG_ONCOMMIT_PRESERVE_ROWS; }
| /*EMPTY*/ { $$ = PG_ONCOMMIT_NOOP; }
;
reloptions:
'(' reloption_list ')' { $$ = $2; }
;
opt_no_inherit: NO INHERIT { $$ = true; }
| /* EMPTY */ { $$ = false; }
;
TableConstraint:
CONSTRAINT name ConstraintElem
{
PGConstraint *n = castNode(PGConstraint, $3);
n->conname = $2;
n->location = @1;
$$ = (PGNode *) n;
}
| ConstraintElem { $$ = $1; }
;
TableLikeOption:
COMMENTS { $$ = PG_CREATE_TABLE_LIKE_COMMENTS; }
| CONSTRAINTS { $$ = PG_CREATE_TABLE_LIKE_CONSTRAINTS; }
| DEFAULTS { $$ = PG_CREATE_TABLE_LIKE_DEFAULTS; }
| IDENTITY_P { $$ = PG_CREATE_TABLE_LIKE_IDENTITY; }
| INDEXES { $$ = PG_CREATE_TABLE_LIKE_INDEXES; }
| STATISTICS { $$ = PG_CREATE_TABLE_LIKE_STATISTICS; }
| STORAGE { $$ = PG_CREATE_TABLE_LIKE_STORAGE; }
| ALL { $$ = PG_CREATE_TABLE_LIKE_ALL; }
;
reloption_list:
reloption_elem { $$ = list_make1($1); }
| reloption_list ',' reloption_elem { $$ = lappend($1, $3); }
;
ExistingIndex: USING INDEX index_name { $$ = $3; }
;
ConstraintAttr:
DEFERRABLE
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_ATTR_DEFERRABLE;
n->location = @1;
$$ = (PGNode *)n;
}
| NOT DEFERRABLE
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_ATTR_NOT_DEFERRABLE;
n->location = @1;
$$ = (PGNode *)n;
}
| INITIALLY DEFERRED
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_ATTR_DEFERRED;
n->location = @1;
$$ = (PGNode *)n;
}
| INITIALLY IMMEDIATE
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_ATTR_IMMEDIATE;
n->location = @1;
$$ = (PGNode *)n;
}
;
OptWith:
WITH reloptions { $$ = $2; }
| WITH OIDS { $$ = list_make1(makeDefElem("oids", (PGNode *) makeInteger(true), @1)); }
| WITHOUT OIDS { $$ = list_make1(makeDefElem("oids", (PGNode *) makeInteger(false), @1)); }
| /*EMPTY*/ { $$ = NIL; }
;
definition: '(' def_list ')' { $$ = $2; }
;
TableLikeOptionList:
TableLikeOptionList INCLUDING TableLikeOption { $$ = $1 | $3; }
| TableLikeOptionList EXCLUDING TableLikeOption { $$ = $1 & ~$3; }
| /* EMPTY */ { $$ = 0; }
;
generic_option_name:
ColLabel { $$ = $1; }
;
ConstraintAttributeElem:
NOT DEFERRABLE { $$ = CAS_NOT_DEFERRABLE; }
| DEFERRABLE { $$ = CAS_DEFERRABLE; }
| INITIALLY IMMEDIATE { $$ = CAS_INITIALLY_IMMEDIATE; }
| INITIALLY DEFERRED { $$ = CAS_INITIALLY_DEFERRED; }
| NOT VALID { $$ = CAS_NOT_VALID; }
| NO INHERIT { $$ = CAS_NO_INHERIT; }
;
regularColumnDef:
Typename ColQualList
{
PGColumnDef *n = makeNode(PGColumnDef);
n->category = COL_STANDARD;
n->typeName = $1;
n->inhcount = 0;
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
n->collOid = InvalidOid;
SplitColQualList($2, &n->constraints, &n->collClause,
yyscanner);
$$ = (PGNode *) n;
}
;
generatedColumnDef:
opt_Typename GeneratedConstraintElem ColQualList
{
PGColumnDef *n = makeNode(PGColumnDef);
n->category = COL_GENERATED;
n->typeName = $1;
n->inhcount = 0;
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
n->collOid = InvalidOid;
// merge the constraints with the generated column constraint
auto constraints = $3;
if (constraints) {
constraints = lappend(constraints, $2);
} else {
constraints = list_make1($2);
}
SplitColQualList(constraints, &n->constraints, &n->collClause,
yyscanner);
$$ = (PGNode *)n;
}
;
columnDef: ColId regularColumnDef
{
PGColumnDef *n = (PGColumnDef *) $2;
n->colname = $1;
n->location = @1;
$$ = (PGNode *)n;
}
|
ColId generatedColumnDef
{
PGColumnDef *n = (PGColumnDef *) $2;
n->colname = $1;
n->location = @1;
$$ = (PGNode *)n;
}
;
def_list: def_elem { $$ = list_make1($1); }
| def_list ',' def_elem { $$ = lappend($1, $3); }
;
index_name: ColId { $$ = $1; };
TableElement:
columnDef { $$ = $1; }
| TableLikeClause { $$ = $1; }
| TableConstraint { $$ = $1; }
;
def_elem: ColLabel '=' def_arg
{
$$ = makeDefElem($1, (PGNode *) $3, @1);
}
| ColLabel
{
$$ = makeDefElem($1, NULL, @1);
}
;
opt_definition:
WITH definition { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
OptTableElementList:
TableElementList { $$ = $1; }
| TableElementList ',' { $$ = $1; }
| /*EMPTY*/ { $$ = NIL; }
;
columnElem: ColId
{
$$ = (PGNode *) makeString($1);
}
;
opt_column_list:
'(' columnList ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
ColQualList:
ColQualList ColConstraint { $$ = lappend($1, $2); }
| /*EMPTY*/ { $$ = NIL; }
;
key_delete: ON DELETE_P key_action { $$ = $3; }
;
reloption_elem:
ColLabel '=' def_arg
{
$$ = makeDefElem($1, (PGNode *) $3, @1);
}
| ColLabel
{
$$ = makeDefElem($1, NULL, @1);
}
| ColLabel '.' ColLabel '=' def_arg
{
$$ = makeDefElemExtended($1, $3, (PGNode *) $5,
PG_DEFELEM_UNSPEC, @1);
}
| ColLabel '.' ColLabel
{
$$ = makeDefElemExtended($1, $3, NULL, PG_DEFELEM_UNSPEC, @1);
}
;
columnList:
columnElem { $$ = list_make1($1); }
| columnList ',' columnElem { $$ = lappend($1, $3); }
;
columnList_opt_comma:
columnList { $$ = $1; }
| columnList ',' { $$ = $1; }
;
func_type: Typename { $$ = $1; }
| type_function_name attrs '%' TYPE_P
{
$$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->pct_type = true;
$$->location = @1;
}
| SETOF type_function_name attrs '%' TYPE_P
{
$$ = makeTypeNameFromNameList(lcons(makeString($2), $3));
$$->pct_type = true;
$$->setof = true;
$$->location = @2;
}
;
ConstraintElem:
CHECK_P '(' a_expr ')' ConstraintAttributeSpec
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_CHECK;
n->location = @1;
n->raw_expr = $3;
n->cooked_expr = NULL;
processCASbits($5, @5, "CHECK",
NULL, NULL, &n->skip_validation,
&n->is_no_inherit, yyscanner);
n->initially_valid = !n->skip_validation;
$$ = (PGNode *)n;
}
| UNIQUE '(' columnList_opt_comma ')' opt_definition
ConstraintAttributeSpec
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_UNIQUE;
n->location = @1;
n->keys = $3;
n->options = $5;
n->indexname = NULL;
processCASbits($6, @6, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
$$ = (PGNode *)n;
}
| UNIQUE ExistingIndex ConstraintAttributeSpec
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_UNIQUE;
n->location = @1;
n->keys = NIL;
n->options = NIL;
n->indexname = $2;
n->indexspace = NULL;
processCASbits($3, @3, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
$$ = (PGNode *)n;
}
| PRIMARY KEY '(' columnList_opt_comma ')' opt_definition
ConstraintAttributeSpec
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_PRIMARY;
n->location = @1;
n->keys = $4;
n->options = $6;
n->indexname = NULL;
processCASbits($7, @7, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
$$ = (PGNode *)n;
}
| PRIMARY KEY ExistingIndex ConstraintAttributeSpec
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_PRIMARY;
n->location = @1;
n->keys = NIL;
n->options = NIL;
n->indexname = $3;
n->indexspace = NULL;
processCASbits($4, @4, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
$$ = (PGNode *)n;
}
| FOREIGN KEY '(' columnList_opt_comma ')' REFERENCES qualified_name
opt_column_list key_match key_actions ConstraintAttributeSpec
{
PGConstraint *n = makeNode(PGConstraint);
n->contype = PG_CONSTR_FOREIGN;
n->location = @1;
n->pktable = $7;
n->fk_attrs = $4;
n->pk_attrs = $8;
n->fk_matchtype = $9;
n->fk_upd_action = (char) ($10 >> 8);
n->fk_del_action = (char) ($10 & 0xFF);
processCASbits($11, @11, "FOREIGN KEY",
&n->deferrable, &n->initdeferred,
&n->skip_validation, NULL,
yyscanner);
n->initially_valid = !n->skip_validation;
$$ = (PGNode *)n;
}
;
TableElementList:
TableElement
{
$$ = list_make1($1);
}
| TableElementList ',' TableElement
{
$$ = lappend($1, $3);
}
;
key_match: MATCH FULL
{
$$ = PG_FKCONSTR_MATCH_FULL;
}
| MATCH PARTIAL
{
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"),
parser_errposition(@1)));
$$ = PG_FKCONSTR_MATCH_PARTIAL;
}
| MATCH SIMPLE
{
$$ = PG_FKCONSTR_MATCH_SIMPLE;
}
| /*EMPTY*/
{
$$ = PG_FKCONSTR_MATCH_SIMPLE;
}
;
TableLikeClause:
LIKE qualified_name TableLikeOptionList
{
PGTableLikeClause *n = makeNode(PGTableLikeClause);
n->relation = $2;
n->options = $3;
$$ = (PGNode *)n;
}
;
OptTemp: TEMPORARY { $$ = PG_RELPERSISTENCE_TEMP; }
| TEMP { $$ = PG_RELPERSISTENCE_TEMP; }
| LOCAL TEMPORARY { $$ = PG_RELPERSISTENCE_TEMP; }
| LOCAL TEMP { $$ = PG_RELPERSISTENCE_TEMP; }
| GLOBAL TEMPORARY
{
ereport(PGWARNING,
(errmsg("GLOBAL is deprecated in temporary table creation"),
parser_errposition(@1)));
$$ = PG_RELPERSISTENCE_TEMP;
}
| GLOBAL TEMP
{
ereport(PGWARNING,
(errmsg("GLOBAL is deprecated in temporary table creation"),
parser_errposition(@1)));
$$ = PG_RELPERSISTENCE_TEMP;
}
| UNLOGGED { $$ = PG_RELPERSISTENCE_UNLOGGED; }
| /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; }
;
generated_when:
ALWAYS { $$ = PG_ATTRIBUTE_IDENTITY_ALWAYS; }
| BY DEFAULT { $$ = ATTRIBUTE_IDENTITY_BY_DEFAULT; }
;

View File

@@ -0,0 +1,71 @@
/*****************************************************************************
*
* QUERY :
* CREATE TABLE relname AS PGSelectStmt [ WITH [NO] DATA ]
*
*
* Note: SELECT ... INTO is a now-deprecated alternative for this.
*
*****************************************************************************/
CreateAsStmt:
CREATE_P OptTemp TABLE create_as_target AS SelectStmt opt_with_data
{
PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
ctas->query = $6;
ctas->into = $4;
ctas->relkind = PG_OBJECT_TABLE;
ctas->is_select_into = false;
ctas->onconflict = PG_ERROR_ON_CONFLICT;
/* cram additional flags into the PGIntoClause */
$4->rel->relpersistence = $2;
$4->skipData = !($7);
$$ = (PGNode *) ctas;
}
| CREATE_P OptTemp TABLE IF_P NOT EXISTS create_as_target AS SelectStmt opt_with_data
{
PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
ctas->query = $9;
ctas->into = $7;
ctas->relkind = PG_OBJECT_TABLE;
ctas->is_select_into = false;
ctas->onconflict = PG_IGNORE_ON_CONFLICT;
/* cram additional flags into the PGIntoClause */
$7->rel->relpersistence = $2;
$7->skipData = !($10);
$$ = (PGNode *) ctas;
}
| CREATE_P OR REPLACE OptTemp TABLE create_as_target AS SelectStmt opt_with_data
{
PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
ctas->query = $8;
ctas->into = $6;
ctas->relkind = PG_OBJECT_TABLE;
ctas->is_select_into = false;
ctas->onconflict = PG_REPLACE_ON_CONFLICT;
/* cram additional flags into the PGIntoClause */
$6->rel->relpersistence = $4;
$6->skipData = !($9);
$$ = (PGNode *) ctas;
}
;
opt_with_data:
WITH DATA_P { $$ = true; }
| WITH NO DATA_P { $$ = false; }
| /*EMPTY*/ { $$ = true; }
;
create_as_target:
qualified_name opt_column_list OptWith OnCommitOption
{
$$ = makeNode(PGIntoClause);
$$->rel = $1;
$$->colNames = $2;
$$->options = $3;
$$->onCommit = $4;
$$->viewQuery = NULL;
$$->skipData = false; /* might get changed later */
}
;

View File

@@ -0,0 +1,180 @@
/*****************************************************************************
*
* CREATE FUNCTION stmt
*
*****************************************************************************/
CreateFunctionStmt:
CREATE_P OptTemp macro_alias qualified_name table_macro_list
{
PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt);
$4->relpersistence = $2;
n->name = $4;
n->functions = $5;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OptTemp macro_alias IF_P NOT EXISTS qualified_name table_macro_list
{
PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt);
$7->relpersistence = $2;
n->name = $7;
n->functions = $8;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE OptTemp macro_alias qualified_name table_macro_list
{
PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt);
$6->relpersistence = $4;
n->name = $6;
n->functions = $7;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OptTemp macro_alias qualified_name macro_definition_list
{
PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt);
$4->relpersistence = $2;
n->name = $4;
n->functions = $5;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OptTemp macro_alias IF_P NOT EXISTS qualified_name macro_definition_list
{
PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt);
$7->relpersistence = $2;
n->name = $7;
n->functions = $8;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE OptTemp macro_alias qualified_name macro_definition_list
{
PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt);
$6->relpersistence = $4;
n->name = $6;
n->functions = $7;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
table_macro_definition:
param_list AS TABLE select_no_parens
{
PGFunctionDefinition *n = makeNode(PGFunctionDefinition);
n->params = $1;
n->query = $4;
$$ = (PGNode *)n;
}
;
table_macro_definition_parens:
param_list AS TABLE select_with_parens
{
PGFunctionDefinition *n = makeNode(PGFunctionDefinition);
n->params = $1;
n->query = $4;
$$ = (PGNode *)n;
}
;
table_macro_list_internal:
table_macro_definition_parens
{
$$ = list_make1($1);
}
| table_macro_list_internal ',' table_macro_definition_parens
{
$$ = lappend($1, $3);
}
;
table_macro_list:
table_macro_definition
{
$$ = list_make1($1);
}
| table_macro_list_internal
;
macro_definition:
param_list AS a_expr
{
PGFunctionDefinition *n = makeNode(PGFunctionDefinition);
n->params = $1;
n->function = $3;
$$ = (PGNode *)n;
}
;
macro_definition_list:
macro_definition
{
$$ = list_make1($1);
}
| macro_definition_list ',' macro_definition
{
$$ = lappend($1, $3);
}
;
macro_alias:
FUNCTION
| MACRO
;
param_list:
'(' ')'
{
$$ = NIL;
}
| '(' MacroParameterList ',' ')'
{
$$ = $2;
}
| '(' MacroParameterList ')'
{
$$ = $2;
}
;
MacroParameterList:
MacroParameter
{
$$ = list_make1($1);
}
| MacroParameterList ',' MacroParameter
{
$$ = lappend($1, $3);
}
;
MacroParameter:
param_name opt_Typename
{
PGFunctionParameter *n = makeNode(PGFunctionParameter);
n->name = $1;
n->typeName = $2;
n->defaultValue = NULL;
$$ = (PGNode *) n;
}
| param_name opt_Typename COLON_EQUALS a_expr
{
PGFunctionParameter *n = makeNode(PGFunctionParameter);
n->name = $1;
n->typeName = $2;
n->defaultValue = (PGExpr *) $4;
$$ = (PGNode *) n;
}
| param_name opt_Typename EQUALS_GREATER a_expr
{
PGFunctionParameter *n = makeNode(PGFunctionParameter);
n->name = $1;
n->typeName = $2;
n->defaultValue = (PGExpr *) $4;
$$ = (PGNode *) n;
}
;

View File

@@ -0,0 +1,89 @@
/*****************************************************************************
*
* Manipulate a schema
*
*****************************************************************************/
CreateSchemaStmt:
CREATE_P SCHEMA qualified_name OptSchemaEltList
{
PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt);
if ($3->catalogname) {
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("CREATE SCHEMA too many dots: expected \"catalog.schema\" or \"schema\""),
parser_errposition(@3)));
}
if ($3->schemaname) {
n->catalogname = $3->schemaname;
n->schemaname = $3->relname;
} else {
n->schemaname = $3->relname;
}
n->schemaElts = $4;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P SCHEMA IF_P NOT EXISTS qualified_name OptSchemaEltList
{
PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt);
if ($6->catalogname) {
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("CREATE SCHEMA too many dots: expected \"catalog.schema\" or \"schema\""),
parser_errposition(@6)));
}
if ($6->schemaname) {
n->catalogname = $6->schemaname;
n->schemaname = $6->relname;
} else {
n->schemaname = $6->relname;
}
if ($7 != NIL)
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"),
parser_errposition(@7)));
n->schemaElts = $7;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE SCHEMA qualified_name OptSchemaEltList
{
PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt);
if ($5->catalogname) {
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("CREATE SCHEMA too many dots: expected \"catalog.schema\" or \"schema\""),
parser_errposition(@5)));
}
if ($5->schemaname) {
n->catalogname = $5->schemaname;
n->schemaname = $5->relname;
} else {
n->schemaname = $5->relname;
}
n->schemaElts = $6;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
OptSchemaEltList:
OptSchemaEltList schema_stmt
{
if (@$ < 0) /* see comments for YYLLOC_DEFAULT */
@$ = @2;
$$ = lappend($1, $2);
}
| /* EMPTY */
{ $$ = NIL; }
;
schema_stmt:
CreateStmt
| IndexStmt
| CreateSeqStmt
| ViewStmt
;

View File

@@ -0,0 +1,76 @@
/*****************************************************************************
*
* Create a secret
*
*****************************************************************************/
CreateSecretStmt:
CREATE_P opt_persist SECRET opt_secret_name opt_storage_specifier '(' create_secret_generic_opt_list ')'
{
PGCreateSecretStmt *n = makeNode(PGCreateSecretStmt);
n->persist_type = $2;
n->secret_name = $4;
n->secret_storage = $5;
n->options = $7;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P opt_persist SECRET IF_P NOT EXISTS opt_secret_name opt_storage_specifier '(' create_secret_generic_opt_list ')'
{
PGCreateSecretStmt *n = makeNode(PGCreateSecretStmt);
n->persist_type = $2;
n->secret_name = $7;
n->secret_storage = $8;
n->options = $10;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE opt_persist SECRET opt_secret_name opt_storage_specifier '(' create_secret_generic_opt_list ')'
{
PGCreateSecretStmt *n = makeNode(PGCreateSecretStmt);
n->persist_type = $4;
n->secret_name = $6;
n->secret_storage = $7;
n->options = $9;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
opt_secret_name:
/* empty */ { $$ = NULL; }
| ColId { $$ = $1; }
;
opt_persist:
/* empty */ { $$ = pstrdup("default"); }
| TEMPORARY { $$ = pstrdup("temporary"); }
| PERSISTENT { $$ = pstrdup("persistent"); }
;
opt_storage_specifier:
/* empty */ { $$ = pstrdup(""); }
| IN_P IDENT { $$ = $2; }
;
create_secret_generic_opt_arg:
a_expr { $$ = (PGNode *) $1; }
;
create_secret_generic_opt_elem:
ColLabel create_secret_generic_opt_arg
{
$$ = makeDefElem($1, $2, @1);
}
;
create_secret_generic_opt_list:
create_secret_generic_opt_elem
{
$$ = list_make1($1);
}
| create_secret_generic_opt_list ',' create_secret_generic_opt_elem
{
$$ = lappend($1, $3);
}
;

View File

@@ -0,0 +1,44 @@
/*****************************************************************************
*
* QUERY :
* CREATE SEQUENCE seqname
* ALTER SEQUENCE seqname
*
*****************************************************************************/
CreateSeqStmt:
CREATE_P OptTemp SEQUENCE qualified_name OptSeqOptList
{
PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt);
$4->relpersistence = $2;
n->sequence = $4;
n->options = $5;
n->ownerId = InvalidOid;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OptTemp SEQUENCE IF_P NOT EXISTS qualified_name OptSeqOptList
{
PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt);
$7->relpersistence = $2;
n->sequence = $7;
n->options = $8;
n->ownerId = InvalidOid;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE OptTemp SEQUENCE qualified_name OptSeqOptList
{
PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt);
$6->relpersistence = $4;
n->sequence = $6;
n->options = $7;
n->ownerId = InvalidOid;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
OptSeqOptList: SeqOptList { $$ = $1; }
| /*EMPTY*/ { $$ = NIL; }
;

View File

@@ -0,0 +1,83 @@
/*****************************************************************************
*
* Create Type Statement
*
*****************************************************************************/
CreateTypeStmt:
CREATE_P OptTemp TYPE_P qualified_name AS create_type_value
{
PGCreateTypeStmt *n = (PGCreateTypeStmt *) $6;
$4->relpersistence = $2;
n->typeName = $4;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OptTemp TYPE_P IF_P NOT EXISTS qualified_name AS create_type_value
{
PGCreateTypeStmt *n = (PGCreateTypeStmt *) $9;
$7->relpersistence = $2;
n->typeName = $7;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P OR REPLACE OptTemp TYPE_P qualified_name AS create_type_value
{
PGCreateTypeStmt *n = (PGCreateTypeStmt *) $8;
$6->relpersistence = $4;
n->typeName = $6;
n->onconflict = PG_REPLACE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
create_type_value:
ENUM_P select_with_parens
{
PGCreateTypeStmt *n = makeNode(PGCreateTypeStmt);
n->kind = PG_NEWTYPE_ENUM;
n->query = $2;
n->vals = NULL;
$$ = (PGNode *)n;
}
| ENUM_P '(' opt_enum_val_list ')'
{
PGCreateTypeStmt *n = makeNode(PGCreateTypeStmt);
n->kind = PG_NEWTYPE_ENUM;
n->vals = $3;
n->query = NULL;
$$ = (PGNode *)n;
}
| Typename
{
PGCreateTypeStmt *n = makeNode(PGCreateTypeStmt);
n->query = NULL;
auto name = std::string(reinterpret_cast<PGValue *>($1->names->tail->data.ptr_value)->val.str);
if (name == "enum") {
n->kind = PG_NEWTYPE_ENUM;
n->vals = $1->typmods;
} else {
n->kind = PG_NEWTYPE_ALIAS;
n->ofType = $1;
}
$$ = (PGNode *)n;
}
;
opt_enum_val_list:
enum_val_list { $$ = $1;}
| {$$ = NIL;}
;
enum_val_list: Sconst
{
$$ = list_make1(makeStringConst($1, @1));
}
| enum_val_list ',' Sconst
{
$$ = lappend($1, makeStringConst($3, @3));
}
;

View File

@@ -0,0 +1,31 @@
/*****************************************************************************
*
* QUERY:
* DEALLOCATE [PREPARE] <plan_name>
*
*****************************************************************************/
DeallocateStmt: DEALLOCATE name
{
PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
n->name = $2;
$$ = (PGNode *) n;
}
| DEALLOCATE PREPARE name
{
PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
n->name = $3;
$$ = (PGNode *) n;
}
| DEALLOCATE ALL
{
PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
n->name = NULL;
$$ = (PGNode *) n;
}
| DEALLOCATE PREPARE ALL
{
PGDeallocateStmt *n = makeNode(PGDeallocateStmt);
n->name = NULL;
$$ = (PGNode *) n;
}
;

View File

@@ -0,0 +1,62 @@
/*****************************************************************************
*
* QUERY:
* DELETE STATEMENTS
*
*****************************************************************************/
DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias
using_clause where_or_current_clause returning_clause
{
PGDeleteStmt *n = makeNode(PGDeleteStmt);
n->relation = $4;
n->usingClause = $5;
n->whereClause = $6;
n->returningList = $7;
n->withClause = $1;
$$ = (PGNode *)n;
}
| TRUNCATE opt_table relation_expr_opt_alias
{
PGDeleteStmt *n = makeNode(PGDeleteStmt);
n->relation = $3;
n->usingClause = NULL;
n->whereClause = NULL;
n->returningList = NULL;
n->withClause = NULL;
$$ = (PGNode *)n;
}
;
relation_expr_opt_alias: relation_expr %prec UMINUS
{
$$ = $1;
}
| relation_expr ColId
{
PGAlias *alias = makeNode(PGAlias);
alias->aliasname = $2;
$1->alias = alias;
$$ = $1;
}
| relation_expr AS ColId
{
PGAlias *alias = makeNode(PGAlias);
alias->aliasname = $3;
$1->alias = alias;
$$ = $1;
}
;
where_or_current_clause:
WHERE a_expr { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
;
using_clause:
USING from_list_opt_comma { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;

View File

@@ -0,0 +1,125 @@
/*****************************************************************************
*
* QUERY:
*
* DROP itemtype [ IF EXISTS ] itemname [, itemname ...]
* [ RESTRICT | CASCADE ]
*
*****************************************************************************/
DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior
{
PGDropStmt *n = makeNode(PGDropStmt);
n->removeType = $2;
n->missing_ok = true;
n->objects = $5;
n->behavior = $6;
n->concurrent = false;
$$ = (PGNode *)n;
}
| DROP drop_type_any_name any_name_list opt_drop_behavior
{
PGDropStmt *n = makeNode(PGDropStmt);
n->removeType = $2;
n->missing_ok = false;
n->objects = $3;
n->behavior = $4;
n->concurrent = false;
$$ = (PGNode *)n;
}
| DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior
{
PGDropStmt *n = makeNode(PGDropStmt);
n->removeType = $2;
n->missing_ok = true;
n->objects = $5;
n->behavior = $6;
n->concurrent = false;
$$ = (PGNode *)n;
}
| DROP drop_type_name name_list opt_drop_behavior
{
PGDropStmt *n = makeNode(PGDropStmt);
n->removeType = $2;
n->missing_ok = false;
n->objects = $3;
n->behavior = $4;
n->concurrent = false;
$$ = (PGNode *)n;
}
| DROP drop_type_name_on_any_name name ON any_name opt_drop_behavior
{
PGDropStmt *n = makeNode(PGDropStmt);
n->removeType = $2;
n->objects = list_make1(lappend($5, makeString($3)));
n->behavior = $6;
n->missing_ok = false;
n->concurrent = false;
$$ = (PGNode *) n;
}
| DROP drop_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior
{
PGDropStmt *n = makeNode(PGDropStmt);
n->removeType = $2;
n->objects = list_make1(lappend($7, makeString($5)));
n->behavior = $8;
n->missing_ok = true;
n->concurrent = false;
$$ = (PGNode *) n;
}
;
drop_type_any_name:
TABLE { $$ = PG_OBJECT_TABLE; }
| SEQUENCE { $$ = PG_OBJECT_SEQUENCE; }
| FUNCTION { $$ = PG_OBJECT_FUNCTION; }
| MACRO { $$ = PG_OBJECT_FUNCTION; }
| MACRO TABLE { $$ = PG_OBJECT_TABLE_MACRO; }
| VIEW { $$ = PG_OBJECT_VIEW; }
| MATERIALIZED VIEW { $$ = PG_OBJECT_MATVIEW; }
| INDEX { $$ = PG_OBJECT_INDEX; }
| FOREIGN TABLE { $$ = PG_OBJECT_FOREIGN_TABLE; }
| COLLATION { $$ = PG_OBJECT_COLLATION; }
| CONVERSION_P { $$ = PG_OBJECT_CONVERSION; }
| SCHEMA { $$ = PG_OBJECT_SCHEMA; }
| STATISTICS { $$ = PG_OBJECT_STATISTIC_EXT; }
| TEXT_P SEARCH PARSER { $$ = PG_OBJECT_TSPARSER; }
| TEXT_P SEARCH DICTIONARY { $$ = PG_OBJECT_TSDICTIONARY; }
| TEXT_P SEARCH TEMPLATE { $$ = PG_OBJECT_TSTEMPLATE; }
| TEXT_P SEARCH CONFIGURATION { $$ = PG_OBJECT_TSCONFIGURATION; }
| TYPE_P { $$ = PG_OBJECT_TYPE; }
;
drop_type_name:
ACCESS METHOD { $$ = PG_OBJECT_ACCESS_METHOD; }
| EVENT TRIGGER { $$ = PG_OBJECT_EVENT_TRIGGER; }
| EXTENSION { $$ = PG_OBJECT_EXTENSION; }
| FOREIGN DATA_P WRAPPER { $$ = PG_OBJECT_FDW; }
| PUBLICATION { $$ = PG_OBJECT_PUBLICATION; }
| SERVER { $$ = PG_OBJECT_FOREIGN_SERVER; }
;
any_name_list:
any_name { $$ = list_make1($1); }
| any_name_list ',' any_name { $$ = lappend($1, $3); }
;
opt_drop_behavior:
CASCADE { $$ = PG_DROP_CASCADE; }
| RESTRICT { $$ = PG_DROP_RESTRICT; }
| /* EMPTY */ { $$ = PG_DROP_RESTRICT; /* default */ }
;
drop_type_name_on_any_name:
POLICY { $$ = PG_OBJECT_POLICY; }
| RULE { $$ = PG_OBJECT_RULE; }
| TRIGGER { $$ = PG_OBJECT_TRIGGER; }
;
type_name_list:
Typename { $$ = list_make1($1); }
| type_name_list ',' Typename { $$ = lappend($1, $3); }
;

View File

@@ -0,0 +1,30 @@
/*****************************************************************************
*
* Drop a secret
*
*****************************************************************************/
DropSecretStmt:
DROP opt_persist SECRET ColId opt_storage_drop_specifier
{
PGDropSecretStmt *n = makeNode(PGDropSecretStmt);
n->persist_type = $2;
n->secret_name = $4;
n->secret_storage = $5;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| DROP opt_persist SECRET IF_P EXISTS ColId opt_storage_drop_specifier
{
PGDropSecretStmt *n = makeNode(PGDropSecretStmt);
n->persist_type = $2;
n->secret_name = $6;
n->secret_storage = $7;
n->missing_ok = true;
$$ = (PGNode *)n;
}
;
opt_storage_drop_specifier:
/* empty */ { $$ = pstrdup(""); }
| FROM IDENT { $$ = $2; }
;

View File

@@ -0,0 +1,77 @@
/*****************************************************************************
*
* EXECUTE <plan_name> [(params, ...)]
* CREATE TABLE <name> AS EXECUTE <plan_name> [(params, ...)]
*
*****************************************************************************/
ExecuteStmt: EXECUTE name execute_param_clause
{
PGExecuteStmt *n = makeNode(PGExecuteStmt);
n->name = $2;
n->params = $3;
$$ = (PGNode *) n;
}
| CREATE_P OptTemp TABLE create_as_target AS
EXECUTE name execute_param_clause opt_with_data
{
PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
PGExecuteStmt *n = makeNode(PGExecuteStmt);
n->name = $7;
n->params = $8;
ctas->query = (PGNode *) n;
ctas->into = $4;
ctas->relkind = PG_OBJECT_TABLE;
ctas->is_select_into = false;
ctas->onconflict = PG_ERROR_ON_CONFLICT;
/* cram additional flags into the PGIntoClause */
$4->rel->relpersistence = $2;
$4->skipData = !($9);
$$ = (PGNode *) ctas;
}
| CREATE_P OptTemp TABLE IF_P NOT EXISTS create_as_target AS
EXECUTE name execute_param_clause opt_with_data
{
PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt);
PGExecuteStmt *n = makeNode(PGExecuteStmt);
n->name = $10;
n->params = $11;
ctas->query = (PGNode *) n;
ctas->into = $7;
ctas->relkind = PG_OBJECT_TABLE;
ctas->is_select_into = false;
ctas->onconflict = PG_IGNORE_ON_CONFLICT;
/* cram additional flags into the PGIntoClause */
$7->rel->relpersistence = $2;
$7->skipData = !($12);
$$ = (PGNode *) ctas;
}
;
execute_param_expr: a_expr
{
$$ = $1;
}
| param_name COLON_EQUALS a_expr
{
PGNamedArgExpr *na = makeNode(PGNamedArgExpr);
na->name = $1;
na->arg = (PGExpr *) $3;
na->argnumber = -1; /* until determined */
na->location = @1;
$$ = (PGNode *) na;
}
execute_param_list: execute_param_expr
{
$$ = list_make1($1);
}
| execute_param_list ',' execute_param_expr
{
$$ = lappend($1, $3);
}
;
execute_param_clause: '(' execute_param_list ')' { $$ = $2; }
| /* EMPTY */ { $$ = NIL; }
;

View File

@@ -0,0 +1,146 @@
/*****************************************************************************
*
* QUERY:
* EXPLAIN [ANALYZE] [VERBOSE] query
* EXPLAIN ( options ) query
*
*****************************************************************************/
ExplainStmt:
EXPLAIN ExplainableStmt
{
PGExplainStmt *n = makeNode(PGExplainStmt);
n->query = $2;
n->options = NIL;
$$ = (PGNode *) n;
}
| EXPLAIN analyze_keyword opt_verbose ExplainableStmt
{
PGExplainStmt *n = makeNode(PGExplainStmt);
n->query = $4;
n->options = list_make1(makeDefElem("analyze", NULL, @2));
if ($3)
n->options = lappend(n->options,
makeDefElem("verbose", NULL, @3));
$$ = (PGNode *) n;
}
| EXPLAIN VERBOSE ExplainableStmt
{
PGExplainStmt *n = makeNode(PGExplainStmt);
n->query = $3;
n->options = list_make1(makeDefElem("verbose", NULL, @2));
$$ = (PGNode *) n;
}
| EXPLAIN '(' explain_option_list ')' ExplainableStmt
{
PGExplainStmt *n = makeNode(PGExplainStmt);
n->query = $5;
n->options = $3;
$$ = (PGNode *) n;
}
;
opt_verbose:
VERBOSE { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
explain_option_arg:
opt_boolean_or_string { $$ = (PGNode *) makeString($1); }
| NumericOnly { $$ = (PGNode *) $1; }
| /* EMPTY */ { $$ = NULL; }
;
ExplainableStmt:
AlterObjectSchemaStmt
| AlterSeqStmt
| AlterTableStmt
| CallStmt
| CheckPointStmt
| CopyStmt
| CreateAsStmt
| CreateFunctionStmt
| CreateSchemaStmt
| CreateSeqStmt
| CreateStmt
| CreateTypeStmt
| DeallocateStmt
| DeleteStmt
| DropStmt
| ExecuteStmt
| IndexStmt
| InsertStmt
| LoadStmt
| MergeIntoStmt
| PragmaStmt
| PrepareStmt
| RenameStmt
| SelectStmt
| TransactionStmt
| UpdateStmt
| UpdateExtensionsStmt
| VacuumStmt
| VariableResetStmt
| VariableSetStmt
| VariableShowStmt
| ViewStmt
;
NonReservedWord: IDENT { $$ = $1; }
| unreserved_keyword { $$ = pstrdup($1); }
| other_keyword { $$ = pstrdup($1); }
;
NonReservedWord_or_Sconst:
NonReservedWord { $$ = $1; }
| Sconst { $$ = $1; }
;
explain_option_list:
explain_option_elem
{
$$ = list_make1($1);
}
| explain_option_list ',' explain_option_elem
{
$$ = lappend($1, $3);
}
;
analyze_keyword:
ANALYZE {}
| ANALYSE /* British */ {}
;
opt_boolean_or_string:
TRUE_P { $$ = (char*) "true"; }
| FALSE_P { $$ = (char*) "false"; }
| ON { $$ = (char*) "on"; }
/*
* OFF is also accepted as a boolean value, but is handled by
* the NonReservedWord rule. The action for booleans and strings
* is the same, so we don't need to distinguish them here.
*/
| NonReservedWord_or_Sconst { $$ = $1; }
;
explain_option_elem:
explain_option_name explain_option_arg
{
$$ = makeDefElem($1, $2, @1);
}
;
explain_option_name:
NonReservedWord { $$ = $1; }
| analyze_keyword { $$ = (char*) "analyze"; }
;

View File

@@ -0,0 +1,39 @@
/*****************************************************************************
*
* EXPORT/IMPORT stmt
*
*****************************************************************************/
ExportStmt:
EXPORT_P DATABASE Sconst copy_options
{
PGExportStmt *n = makeNode(PGExportStmt);
n->database = NULL;
n->filename = $3;
n->options = NIL;
if ($4) {
n->options = list_concat(n->options, $4);
}
$$ = (PGNode *)n;
}
|
EXPORT_P DATABASE ColId TO Sconst copy_options
{
PGExportStmt *n = makeNode(PGExportStmt);
n->database = $3;
n->filename = $5;
n->options = NIL;
if ($6) {
n->options = list_concat(n->options, $6);
}
$$ = (PGNode *)n;
}
;
ImportStmt:
IMPORT_P DATABASE Sconst
{
PGImportStmt *n = makeNode(PGImportStmt);
n->filename = $3;
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,91 @@
/*****************************************************************************
*
* QUERY: CREATE INDEX
*
* Note: we cannot put TABLESPACE clause after WHERE clause unless we are
* willing to make TABLESPACE a fully reserved word.
*****************************************************************************/
IndexStmt: CREATE_P opt_unique INDEX opt_concurrently opt_index_name
ON qualified_name access_method_clause '(' index_params ')'
opt_reloptions where_clause
{
PGIndexStmt *n = makeNode(PGIndexStmt);
n->unique = $2;
n->concurrent = $4;
n->idxname = $5;
n->relation = $7;
n->accessMethod = $8;
n->indexParams = $10;
n->options = $12;
n->whereClause = $13;
n->excludeOpNames = NIL;
n->idxcomment = NULL;
n->indexOid = InvalidOid;
n->oldNode = InvalidOid;
n->primary = false;
n->isconstraint = false;
n->deferrable = false;
n->initdeferred = false;
n->transformed = false;
n->onconflict = PG_ERROR_ON_CONFLICT;
$$ = (PGNode *)n;
}
| CREATE_P opt_unique INDEX opt_concurrently IF_P NOT EXISTS index_name
ON qualified_name access_method_clause '(' index_params ')'
opt_reloptions where_clause
{
PGIndexStmt *n = makeNode(PGIndexStmt);
n->unique = $2;
n->concurrent = $4;
n->idxname = $8;
n->relation = $10;
n->accessMethod = $11;
n->indexParams = $13;
n->options = $15;
n->whereClause = $16;
n->excludeOpNames = NIL;
n->idxcomment = NULL;
n->indexOid = InvalidOid;
n->oldNode = InvalidOid;
n->primary = false;
n->isconstraint = false;
n->deferrable = false;
n->initdeferred = false;
n->transformed = false;
n->onconflict = PG_IGNORE_ON_CONFLICT;
$$ = (PGNode *)n;
}
;
access_method:
ColId { $$ = $1; };
access_method_clause:
USING access_method { $$ = $2; }
| /*EMPTY*/ { $$ = (char*) DEFAULT_INDEX_TYPE; }
;
opt_concurrently:
CONCURRENTLY { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
opt_index_name:
index_name { $$ = $1; }
| /*EMPTY*/ { $$ = NULL; }
;
opt_reloptions: WITH reloptions { $$ = $2; }
| /* EMPTY */ { $$ = NIL; }
;
opt_unique:
UNIQUE { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;

View File

@@ -0,0 +1,291 @@
/*****************************************************************************
*
* QUERY:
* INSERT STATEMENTS
*
*****************************************************************************/
InsertStmt:
opt_with_clause INSERT opt_or_action INTO insert_target opt_by_name_or_position insert_rest
opt_on_conflict returning_clause
{
$7->relation = $5;
$7->onConflictAlias = $3;
$7->onConflictClause = $8;
$7->returningList = $9;
$7->withClause = $1;
$7->insert_column_order = $6;
$$ = (PGNode *) $7;
}
;
insert_rest:
SelectStmt
{
$$ = makeNode(PGInsertStmt);
$$->cols = NIL;
$$->selectStmt = $1;
}
| OVERRIDING override_kind VALUE_P SelectStmt
{
$$ = makeNode(PGInsertStmt);
$$->cols = NIL;
$$->override = $2;
$$->selectStmt = $4;
}
| '(' insert_column_list ')' SelectStmt
{
$$ = makeNode(PGInsertStmt);
$$->cols = $2;
$$->selectStmt = $4;
}
| '(' insert_column_list ')' OVERRIDING override_kind VALUE_P SelectStmt
{
$$ = makeNode(PGInsertStmt);
$$->cols = $2;
$$->override = $5;
$$->selectStmt = $7;
}
| DEFAULT VALUES
{
$$ = makeNode(PGInsertStmt);
$$->cols = NIL;
$$->selectStmt = NULL;
}
;
insert_target:
qualified_name
{
$$ = $1;
}
| qualified_name AS ColId
{
$1->alias = makeAlias($3, NIL);
$$ = $1;
}
;
opt_by_name_or_position:
BY NAME_P { $$ = PG_INSERT_BY_NAME; }
| BY POSITION { $$ = PG_INSERT_BY_POSITION; }
| /* empty */ { $$ = PG_INSERT_BY_POSITION; }
;
opt_conf_expr:
'(' index_params ')' where_clause
{
$$ = makeNode(PGInferClause);
$$->indexElems = $2;
$$->whereClause = $4;
$$->conname = NULL;
$$->location = @1;
}
|
ON CONSTRAINT name
{
$$ = makeNode(PGInferClause);
$$->indexElems = NIL;
$$->whereClause = NULL;
$$->conname = $3;
$$->location = @1;
}
| /*EMPTY*/
{
$$ = NULL;
}
;
opt_with_clause:
with_clause { $$ = $1; }
| /*EMPTY*/ { $$ = NULL; }
;
insert_column_item:
ColId opt_indirection
{
$$ = makeNode(PGResTarget);
$$->name = $1;
$$->indirection = check_indirection($2, yyscanner);
$$->val = NULL;
$$->location = @1;
}
;
set_clause:
set_target '=' a_expr
{
$1->val = (PGNode *) $3;
$$ = list_make1($1);
}
| '(' set_target_list ')' '=' a_expr
{
int ncolumns = list_length($2);
int i = 1;
PGListCell *col_cell;
/* Create a PGMultiAssignRef source for each target */
foreach(col_cell, $2)
{
PGResTarget *res_col = (PGResTarget *) lfirst(col_cell);
PGMultiAssignRef *r = makeNode(PGMultiAssignRef);
r->source = (PGNode *) $5;
r->colno = i;
r->ncolumns = ncolumns;
res_col->val = (PGNode *) r;
i++;
}
$$ = $2;
}
;
opt_or_action:
OR REPLACE
{
$$ = PG_ONCONFLICT_ALIAS_REPLACE;
}
|
OR IGNORE_P
{
$$ = PG_ONCONFLICT_ALIAS_IGNORE;
}
| /*EMPTY*/
{
$$ = PG_ONCONFLICT_ALIAS_NONE;
}
;
opt_on_conflict:
ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list_opt_comma where_clause
{
$$ = makeNode(PGOnConflictClause);
$$->action = PG_ONCONFLICT_UPDATE;
$$->infer = $3;
$$->targetList = $7;
$$->whereClause = $8;
$$->location = @1;
}
|
ON CONFLICT opt_conf_expr DO NOTHING
{
$$ = makeNode(PGOnConflictClause);
$$->action = PG_ONCONFLICT_NOTHING;
$$->infer = $3;
$$->targetList = NIL;
$$->whereClause = NULL;
$$->location = @1;
}
| /*EMPTY*/
{
$$ = NULL;
}
;
index_elem: ColId opt_collate opt_class opt_asc_desc opt_nulls_order
{
$$ = makeNode(PGIndexElem);
$$->name = $1;
$$->expr = NULL;
$$->indexcolname = NULL;
$$->collation = $2;
$$->opclass = $3;
$$->ordering = $4;
$$->nulls_ordering = $5;
}
| func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order
{
$$ = makeNode(PGIndexElem);
$$->name = NULL;
$$->expr = $1;
$$->indexcolname = NULL;
$$->collation = $2;
$$->opclass = $3;
$$->ordering = $4;
$$->nulls_ordering = $5;
}
| '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order
{
$$ = makeNode(PGIndexElem);
$$->name = NULL;
$$->expr = $2;
$$->indexcolname = NULL;
$$->collation = $4;
$$->opclass = $5;
$$->ordering = $6;
$$->nulls_ordering = $7;
}
;
returning_clause:
RETURNING target_list { $$ = $2; }
| /* EMPTY */ { $$ = NIL; }
;
override_kind:
USER { $$ = PG_OVERRIDING_USER_VALUE; }
| SYSTEM_P { $$ = OVERRIDING_SYSTEM_VALUE; }
;
set_target_list:
set_target { $$ = list_make1($1); }
| set_target_list ',' set_target { $$ = lappend($1,$3); }
;
opt_collate: COLLATE any_name { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
opt_class: any_name { $$ = $1; }
| /*EMPTY*/ { $$ = NIL; }
;
insert_column_list:
insert_column_item
{ $$ = list_make1($1); }
| insert_column_list ',' insert_column_item
{ $$ = lappend($1, $3); }
;
set_clause_list:
set_clause { $$ = $1; }
| set_clause_list ',' set_clause { $$ = list_concat($1,$3); }
;
set_clause_list_opt_comma:
set_clause_list { $$ = $1; }
| set_clause_list ',' { $$ = $1; }
;
index_params: index_elem { $$ = list_make1($1); }
| index_params ',' index_elem { $$ = lappend($1, $3); }
;
set_target:
ColId opt_indirection
{
$$ = makeNode(PGResTarget);
$$->name = $1;
$$->indirection = check_indirection($2, yyscanner);
$$->val = NULL; /* upper production sets this */
$$->location = @1;
}
;

View File

@@ -0,0 +1,55 @@
/*****************************************************************************
*
* QUERY:
* LOAD "filename"
*
*****************************************************************************/
LoadStmt: LOAD file_name
{
PGLoadStmt *n = makeNode(PGLoadStmt);
n->filename = $2;
n->repository = NULL;
n->repo_is_alias = false;
n->version = NULL;
n->load_type = PG_LOAD_TYPE_LOAD;
$$ = (PGNode *)n;
} |
opt_force INSTALL file_name opt_ext_version {
PGLoadStmt *n = makeNode(PGLoadStmt);
n->filename = $3;
n->repository = NULL;
n->repo_is_alias = false;
n->version = $4;
n->load_type = $1;
$$ = (PGNode *)n;
} |
opt_force INSTALL file_name FROM ColId opt_ext_version {
PGLoadStmt *n = makeNode(PGLoadStmt);
n->repository = $5;
n->repo_is_alias = true;
n->filename = $3;
n->version = $6;
n->load_type = $1;
$$ = (PGNode *)n;
} |
opt_force INSTALL file_name FROM Sconst opt_ext_version {
PGLoadStmt *n = makeNode(PGLoadStmt);
n->filename = $3;
n->repository = $5;
n->repo_is_alias = false;
n->version = $6;
n->load_type = $1;
$$ = (PGNode *)n;
}
;
opt_force: /* empty*/ { $$ = PG_LOAD_TYPE_INSTALL; } |
FORCE { $$ = PG_LOAD_TYPE_FORCE_INSTALL; };
file_name: Sconst { $$ = $1; } |
ColId { $$ = $1; };
opt_ext_version:
/* empty */ { $$ = NULL; } |
VERSION_P Sconst { $$ = $2; } |
VERSION_P ColId { $$ = $2; };

View File

@@ -0,0 +1,148 @@
/*****************************************************************************
*
* QUERY:
* MERGE INTO
*
*****************************************************************************/
MergeIntoStmt: opt_with_clause
MERGE INTO relation_expr_opt_alias
USING table_ref
join_qual
merge_match_list
returning_clause
{
PGMergeIntoStmt *n = makeNode(PGMergeIntoStmt);
n->targetTable = $4;
n->source = $6;
if ($5 != NULL && IsA($7, PGList))
n->usingClause = (PGList *) $7; /* USING clause */
else
n->joinCondition = $7; /* ON clause */
n->matchActions = $8;
n->withClause = $1;
n->returningList = $9;
$$ = (PGNode *)n;
}
;
opt_and_clause:
AND a_expr { $$ = $2; }
| /* EMPTY */ { $$ = NULL; }
;
opt_insert_column_list:
'(' insert_column_list ')' { $$ = $2; }
| /* EMPTY */ { $$ = NULL; }
;
opt_star_expr:
'*' | /* EMPTY */
;
matched_clause_action:
UPDATE SET set_clause_list_opt_comma
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_UPDATE;
n->insert_column_order = PG_INSERT_BY_POSITION;
n->updateTargets = $3;
$$ = (PGNode *)n;
}
| UPDATE SET '*'
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_UPDATE;
n->insert_column_order = PG_INSERT_BY_POSITION;
$$ = (PGNode *)n;
}
| UPDATE opt_by_name_or_position
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_UPDATE;
n->insert_column_order = $2;
$$ = (PGNode *)n;
}
| DELETE_P
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_DELETE;
$$ = (PGNode *)n;
}
| INSERT opt_insert_column_list VALUES '(' expr_list_opt_comma ')'
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_INSERT;
n->insert_column_order = PG_INSERT_BY_POSITION;
n->insertCols = $2;
n->insertValues = $5;
$$ = (PGNode *)n;
}
| INSERT opt_by_name_or_position opt_star_expr
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_INSERT;
n->insert_column_order = $2;
$$ = (PGNode *)n;
}
| INSERT DEFAULT VALUES
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_INSERT;
n->insert_column_order = PG_INSERT_BY_POSITION;
n->defaultValues = true;
$$ = (PGNode *)n;
}
| DO NOTHING
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_DO_NOTHING;
$$ = (PGNode *)n;
}
| ERROR_P opt_error_message
{
PGMatchAction *n = makeNode(PGMatchAction);
n->actionType = MERGE_ACTION_TYPE_ERROR;
n->errorMessage = $2;
$$ = (PGNode *)n;
}
;
opt_error_message:
a_expr { $$ = $1; }
| /* EMPTY */ { $$ = NULL; }
;
matched_clause:
WHEN MATCHED opt_and_clause THEN matched_clause_action
{
PGMatchAction *n = (PGMatchAction *) $5;
n->when = MERGE_ACTION_WHEN_MATCHED;
n->andClause = $3;
$$ = (PGNode *)n;
}
;
opt_source_or_target:
BY SOURCE_P { $$ = MERGE_ACTION_WHEN_NOT_MATCHED_BY_SOURCE; }
| BY TARGET_P { $$ = MERGE_ACTION_WHEN_NOT_MATCHED_BY_TARGET; }
| /* empty */ { $$ = MERGE_ACTION_WHEN_NOT_MATCHED_BY_TARGET; }
;
not_matched_clause:
WHEN NOT MATCHED opt_source_or_target opt_and_clause THEN matched_clause_action
{
PGMatchAction *n = (PGMatchAction *) $7;
n->when = $4;
n->andClause = $5;
$$ = (PGNode *)n;
}
;
matched_or_not_matched_clause:
matched_clause | not_matched_clause
;
merge_match_list:
matched_or_not_matched_clause { $$ = list_make1($1); }
| matched_or_not_matched_clause merge_match_list { $$ = list_concat(list_make1($1), $2); }
;

View File

@@ -0,0 +1,31 @@
/*****************************************************************************
*
* PRAGMA stmt
*
*****************************************************************************/
PragmaStmt:
PRAGMA_P ColId
{
PGPragmaStmt *n = makeNode(PGPragmaStmt);
n->kind = PG_PRAGMA_TYPE_NOTHING;
n->name = $2;
$$ = (PGNode *)n;
}
| PRAGMA_P ColId '=' var_list
{
PGPragmaStmt *n = makeNode(PGPragmaStmt);
n->kind = PG_PRAGMA_TYPE_ASSIGNMENT;
n->name = $2;
n->args = $4;
$$ = (PGNode *)n;
}
| PRAGMA_P ColId '(' func_arg_list ')'
{
PGPragmaStmt *n = makeNode(PGPragmaStmt);
n->kind = PG_PRAGMA_TYPE_CALL;
n->name = $2;
n->args = $4;
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,29 @@
/*****************************************************************************
*
* QUERY:
* PREPARE <plan_name> [(args, ...)] AS <query>
*
*****************************************************************************/
PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt
{
PGPrepareStmt *n = makeNode(PGPrepareStmt);
n->name = $2;
n->argtypes = $3;
n->query = $5;
$$ = (PGNode *) n;
}
;
prep_type_clause: '(' type_list ')' { $$ = $2; }
| /* EMPTY */ { $$ = NIL; }
;
PreparableStmt:
SelectStmt
| InsertStmt
| UpdateStmt
| CopyStmt
| DeleteStmt
| VariableShowStmt /* by default all are $$=$1 */
;

View File

@@ -0,0 +1,142 @@
/*****************************************************************************
*
* ALTER THING name RENAME TO newname
*
*****************************************************************************/
RenameStmt: ALTER SCHEMA name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_SCHEMA;
n->subname = $3;
n->newname = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER TABLE relation_expr RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_TABLE;
n->relation = $3;
n->subname = NULL;
n->newname = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER TABLE IF_P EXISTS relation_expr RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_TABLE;
n->relation = $5;
n->subname = NULL;
n->newname = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE qualified_name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_SEQUENCE;
n->relation = $3;
n->subname = NULL;
n->newname = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER SEQUENCE IF_P EXISTS qualified_name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_SEQUENCE;
n->relation = $5;
n->subname = NULL;
n->newname = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER VIEW qualified_name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_VIEW;
n->relation = $3;
n->subname = NULL;
n->newname = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER VIEW IF_P EXISTS qualified_name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_VIEW;
n->relation = $5;
n->subname = NULL;
n->newname = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER INDEX qualified_name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_INDEX;
n->relation = $3;
n->subname = NULL;
n->newname = $6;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER INDEX IF_P EXISTS qualified_name RENAME TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_INDEX;
n->relation = $5;
n->subname = NULL;
n->newname = $8;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER TABLE relation_expr RENAME opt_column qualified_column TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_COLUMN;
n->relationType = PG_OBJECT_TABLE;
n->relation = $3;
n->name_list = $6;
n->newname = $8;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column qualified_column TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_COLUMN;
n->relationType = PG_OBJECT_TABLE;
n->relation = $5;
n->name_list = $8;
n->newname = $10;
n->missing_ok = true;
$$ = (PGNode *)n;
}
| ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_TABCONSTRAINT;
n->relation = $3;
n->subname = $6;
n->newname = $8;
n->missing_ok = false;
$$ = (PGNode *)n;
}
| ALTER TABLE IF_P EXISTS relation_expr RENAME CONSTRAINT name TO name
{
PGRenameStmt *n = makeNode(PGRenameStmt);
n->renameType = PG_OBJECT_TABCONSTRAINT;
n->relation = $5;
n->subname = $8;
n->newname = $10;
n->missing_ok = true;
$$ = (PGNode *)n;
}
;
opt_column: COLUMN { $$ = COLUMN; }
| /*EMPTY*/ { $$ = 0; }
;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
TransactionStmt:
ABORT_P opt_transaction
{
PGTransactionStmt *n = makeNode(PGTransactionStmt);
n->kind = PG_TRANS_STMT_ROLLBACK;
n->options = NIL;
n->transaction_type = PG_TRANS_TYPE_DEFAULT;
$$ = (PGNode *)n;
}
| BEGIN_P opt_transaction opt_transaction_type
{
PGTransactionStmt *n = makeNode(PGTransactionStmt);
n->kind = PG_TRANS_STMT_BEGIN;
n->transaction_type = $3;
$$ = (PGNode *)n;
}
| START opt_transaction opt_transaction_type
{
PGTransactionStmt *n = makeNode(PGTransactionStmt);
n->kind = PG_TRANS_STMT_START;
n->transaction_type = $3;
$$ = (PGNode *)n;
}
| COMMIT opt_transaction
{
PGTransactionStmt *n = makeNode(PGTransactionStmt);
n->kind = PG_TRANS_STMT_COMMIT;
n->options = NIL;
n->transaction_type = PG_TRANS_TYPE_DEFAULT;
$$ = (PGNode *)n;
}
| END_P opt_transaction
{
PGTransactionStmt *n = makeNode(PGTransactionStmt);
n->kind = PG_TRANS_STMT_COMMIT;
n->options = NIL;
n->transaction_type = PG_TRANS_TYPE_DEFAULT;
$$ = (PGNode *)n;
}
| ROLLBACK opt_transaction
{
PGTransactionStmt *n = makeNode(PGTransactionStmt);
n->kind = PG_TRANS_STMT_ROLLBACK;
n->options = NIL;
n->transaction_type = PG_TRANS_TYPE_DEFAULT;
$$ = (PGNode *)n;
}
;
opt_transaction: WORK {}
| TRANSACTION {}
| /*EMPTY*/ {}
;
opt_transaction_type:
READ_P ONLY { $$ = PG_TRANS_TYPE_READ_ONLY; }
| READ_P WRITE_P { $$ = PG_TRANS_TYPE_READ_WRITE; }
| /*EMPTY*/ { $$ = PG_TRANS_TYPE_DEFAULT; }
;

View File

@@ -0,0 +1,22 @@
/*****************************************************************************
*
* QUERY:
* PGUpdateStmt (UPDATE)
*
*****************************************************************************/
UpdateStmt: opt_with_clause UPDATE relation_expr_opt_alias
SET set_clause_list_opt_comma
from_clause
where_or_current_clause
returning_clause
{
PGUpdateStmt *n = makeNode(PGUpdateStmt);
n->relation = $3;
n->targetList = $5;
n->fromClause = $6;
n->whereClause = $7;
n->returningList = $8;
n->withClause = $1;
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,22 @@
/*****************************************************************************
*
* QUERY:
* PGUpdateExtensionsStmt (UPDATE EXTENSIONS)
*
*****************************************************************************/
UpdateExtensionsStmt: opt_with_clause UPDATE EXTENSIONS opt_column_list
{
PGUpdateExtensionsStmt *n = makeNode(PGUpdateExtensionsStmt);
n->extensions = $4;
if ($1) {
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("Providing a with clause with an UPDATE EXTENSIONS statement is not allowed"),
parser_errposition(@1)));
break;
}
$$ = (PGNode *)n;
}
;

View File

@@ -0,0 +1,8 @@
UseStmt:
USE_P qualified_name
{
PGUseStmt *n = makeNode(PGUseStmt);
n->name = $2;
$$ = (PGNode *) n;
}
;

View File

@@ -0,0 +1,100 @@
/*****************************************************************************
*
* QUERY:
* VACUUM
* ANALYZE
*
*****************************************************************************/
VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
{
PGVacuumStmt *n = makeNode(PGVacuumStmt);
n->options = PG_VACOPT_VACUUM;
if ($2)
n->options |= PG_VACOPT_FULL;
if ($3)
n->options |= PG_VACOPT_FREEZE;
if ($4)
n->options |= PG_VACOPT_VERBOSE;
n->relation = NULL;
n->va_cols = NIL;
$$ = (PGNode *)n;
}
| VACUUM opt_full opt_freeze opt_verbose qualified_name opt_name_list
{
PGVacuumStmt *n = makeNode(PGVacuumStmt);
n->options = PG_VACOPT_VACUUM;
if ($2)
n->options |= PG_VACOPT_FULL;
if ($3)
n->options |= PG_VACOPT_FREEZE;
if ($4)
n->options |= PG_VACOPT_VERBOSE;
n->relation = $5;
n->va_cols = $6;
$$ = (PGNode *)n;
}
| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
{
PGVacuumStmt *n = (PGVacuumStmt *) $5;
n->options |= PG_VACOPT_VACUUM;
if ($2)
n->options |= PG_VACOPT_FULL;
if ($3)
n->options |= PG_VACOPT_FREEZE;
if ($4)
n->options |= PG_VACOPT_VERBOSE;
$$ = (PGNode *)n;
}
| VACUUM '(' vacuum_option_list ')'
{
PGVacuumStmt *n = makeNode(PGVacuumStmt);
n->options = PG_VACOPT_VACUUM | $3;
n->relation = NULL;
n->va_cols = NIL;
$$ = (PGNode *) n;
}
| VACUUM '(' vacuum_option_list ')' qualified_name opt_name_list
{
PGVacuumStmt *n = makeNode(PGVacuumStmt);
n->options = PG_VACOPT_VACUUM | $3;
n->relation = $5;
n->va_cols = $6;
if (n->va_cols != NIL) /* implies analyze */
n->options |= PG_VACOPT_ANALYZE;
$$ = (PGNode *) n;
}
;
vacuum_option_elem:
analyze_keyword { $$ = PG_VACOPT_ANALYZE; }
| VERBOSE { $$ = PG_VACOPT_VERBOSE; }
| FREEZE { $$ = PG_VACOPT_FREEZE; }
| FULL { $$ = PG_VACOPT_FULL; }
| IDENT
{
if (strcmp($1, "disable_page_skipping") == 0)
$$ = PG_VACOPT_DISABLE_PAGE_SKIPPING;
else
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized VACUUM option \"%s\"", $1),
parser_errposition(@1)));
}
;
opt_full: FULL { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
vacuum_option_list:
vacuum_option_elem { $$ = $1; }
| vacuum_option_list ',' vacuum_option_elem { $$ = $1 | $3; }
;
opt_freeze: FREEZE { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;

View File

@@ -0,0 +1,63 @@
VariableResetStmt:
RESET reset_rest
{
$2->scope = VAR_SET_SCOPE_DEFAULT;
$$ = (PGNode *) $2;
}
| RESET LOCAL reset_rest
{
$3->scope = VAR_SET_SCOPE_LOCAL;
$$ = (PGNode *) $3;
}
| RESET SESSION reset_rest
{
$3->scope = VAR_SET_SCOPE_SESSION;
$$ = (PGNode *) $3;
}
| RESET GLOBAL reset_rest
{
$3->scope = VAR_SET_SCOPE_GLOBAL;
$$ = (PGNode *) $3;
}
| RESET VARIABLE_P reset_rest
{
$3->scope = VAR_SET_SCOPE_VARIABLE;
$$ = (PGNode *) $3;
}
;
generic_reset:
var_name
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_RESET;
n->name = $1;
$$ = n;
}
| ALL
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_RESET_ALL;
$$ = n;
}
;
reset_rest:
generic_reset { $$ = $1; }
| TIME ZONE
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_RESET;
n->name = (char*) "timezone";
$$ = n;
}
| TRANSACTION ISOLATION LEVEL
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_RESET;
n->name = (char*) "transaction_isolation";
$$ = n;
}
;

View File

@@ -0,0 +1,139 @@
/*****************************************************************************
*
* Set PG internal variable
* SET name TO 'var_value'
* Include SQL syntax (thomas 1997-10-22):
* SET TIME ZONE 'var_value'
*
*****************************************************************************/
VariableSetStmt:
SET set_rest
{
PGVariableSetStmt *n = $2;
n->scope = VAR_SET_SCOPE_DEFAULT;
$$ = (PGNode *) n;
}
| SET LOCAL set_rest
{
PGVariableSetStmt *n = $3;
n->scope = VAR_SET_SCOPE_LOCAL;
$$ = (PGNode *) n;
}
| SET SESSION set_rest
{
PGVariableSetStmt *n = $3;
n->scope = VAR_SET_SCOPE_SESSION;
$$ = (PGNode *) n;
}
| SET GLOBAL set_rest
{
PGVariableSetStmt *n = $3;
n->scope = VAR_SET_SCOPE_GLOBAL;
$$ = (PGNode *) n;
}
| SET VARIABLE_P set_rest
{
PGVariableSetStmt *n = $3;
n->scope = VAR_SET_SCOPE_VARIABLE;
$$ = (PGNode *) n;
}
;
set_rest: /* Generic SET syntaxes: */
generic_set {$$ = $1;}
| var_name FROM CURRENT_P
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_SET_CURRENT;
n->name = $1;
$$ = n;
}
/* Special syntaxes mandated by SQL standard: */
| TIME ZONE zone_value
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = (char*) "timezone";
if ($3 != NULL)
n->args = list_make1($3);
else
n->kind = VAR_SET_DEFAULT;
$$ = n;
}
| SCHEMA Sconst
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = (char*) "search_path";
n->args = list_make1(makeStringConst($2, @2));
$$ = n;
}
;
generic_set:
var_name TO var_list
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = $1;
n->args = $3;
$$ = n;
}
| var_name '=' var_list
{
PGVariableSetStmt *n = makeNode(PGVariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = $1;
n->args = $3;
$$ = n;
}
;
var_value: a_expr
{ $$ = $1; }
;
zone_value:
Sconst
{
$$ = makeStringConst($1, @1);
}
| IDENT
{
$$ = makeStringConst($1, @1);
}
| ConstInterval Sconst opt_interval
{
PGTypeName *t = $1;
if ($3 != NIL)
{
PGAConst *n = (PGAConst *) linitial($3);
if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
ereport(ERROR,
(errcode(PG_ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
parser_errposition(@3)));
}
t->typmods = $3;
$$ = makeStringConstCast($2, @2, t);
}
| ConstInterval '(' Iconst ')' Sconst
{
PGTypeName *t = $1;
t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
makeIntConst($3, @3));
$$ = makeStringConstCast($5, @5, t);
}
| NumericOnly { $$ = makeAConst($1, @1); }
| DEFAULT { $$ = NULL; }
| LOCAL { $$ = NULL; }
;
var_list: var_value { $$ = list_make1($1); }
| var_list ',' var_value { $$ = lappend($1, $3); }
;

View File

@@ -0,0 +1,78 @@
/* allows SET or RESET without LOCAL */
VariableShowStmt:
show_or_describe SelectStmt {
PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt);
n->stmt = $2;
n->name = (char*) "select";
n->is_summary = 0;
$$ = (PGNode *) n;
}
| SUMMARIZE SelectStmt {
PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt);
n->stmt = $2;
n->name = (char*) "select";
n->is_summary = 1;
$$ = (PGNode *) n;
}
| SUMMARIZE qualified_name
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->relation = $2;
n->is_summary = 1;
$$ = (PGNode *) n;
}
| show_or_describe TABLES FROM qualified_name
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->relation = $4;
n->set = (char*) "__show_tables_from_database";
n->is_summary = 0;
$$ = (PGNode *) n;
}
| show_or_describe qualified_name
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->relation = $2;
n->is_summary = 0;
$$ = (PGNode *) n;
}
| show_or_describe TIME ZONE
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->set = (char*) "timezone";
n->is_summary = 0;
$$ = (PGNode *) n;
}
| show_or_describe TRANSACTION ISOLATION LEVEL
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->set = (char*) "transaction_isolation";
n->is_summary = 0;
$$ = (PGNode *) n;
}
| show_or_describe ALL opt_tables
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->set = (char*) "__show_tables_expanded";
n->is_summary = 0;
$$ = (PGNode *) n;
}
| show_or_describe
{
PGVariableShowStmt *n = makeNode(PGVariableShowStmt);
n->set = (char*) "__show_tables_expanded";
n->is_summary = 0;
$$ = (PGNode *) n;
}
;
describe_or_desc: DESCRIBE | DESC_P
show_or_describe: SHOW | describe_or_desc
opt_tables: TABLES | /* empty */
var_name: ColId { $$ = $1; }
| var_name '.' ColId
{ $$ = psprintf("%s.%s", $1, $3); }
;

View File

@@ -0,0 +1,91 @@
/*****************************************************************************
*
* QUERY:
* CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
* AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
*
*****************************************************************************/
ViewStmt: CREATE_P OptTemp VIEW qualified_name opt_column_list opt_reloptions
AS SelectStmt opt_check_option
{
PGViewStmt *n = makeNode(PGViewStmt);
n->view = $4;
n->view->relpersistence = $2;
n->aliases = $5;
n->query = $8;
n->onconflict = PG_ERROR_ON_CONFLICT;
n->options = $6;
n->withCheckOption = $9;
$$ = (PGNode *) n;
}
| CREATE_P OptTemp VIEW IF_P NOT EXISTS qualified_name opt_column_list opt_reloptions
AS SelectStmt opt_check_option
{
PGViewStmt *n = makeNode(PGViewStmt);
n->view = $7;
n->view->relpersistence = $2;
n->aliases = $8;
n->query = $11;
n->onconflict = PG_IGNORE_ON_CONFLICT;
n->options = $9;
n->withCheckOption = $12;
$$ = (PGNode *) n;
}
| CREATE_P OR REPLACE OptTemp VIEW qualified_name opt_column_list opt_reloptions
AS SelectStmt opt_check_option
{
PGViewStmt *n = makeNode(PGViewStmt);
n->view = $6;
n->view->relpersistence = $4;
n->aliases = $7;
n->query = $10;
n->onconflict = PG_REPLACE_ON_CONFLICT;
n->options = $8;
n->withCheckOption = $11;
$$ = (PGNode *) n;
}
| CREATE_P OptTemp RECURSIVE VIEW qualified_name '(' columnList ')' opt_reloptions
AS SelectStmt opt_check_option
{
PGViewStmt *n = makeNode(PGViewStmt);
n->view = $5;
n->view->relpersistence = $2;
n->aliases = $7;
n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, $11);
n->onconflict = PG_ERROR_ON_CONFLICT;
n->options = $9;
n->withCheckOption = $12;
if (n->withCheckOption != PG_NO_CHECK_OPTION)
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("WITH CHECK OPTION not supported on recursive views"),
parser_errposition(@12)));
$$ = (PGNode *) n;
}
| CREATE_P OR REPLACE OptTemp RECURSIVE VIEW qualified_name '(' columnList ')' opt_reloptions
AS SelectStmt opt_check_option
{
PGViewStmt *n = makeNode(PGViewStmt);
n->view = $7;
n->view->relpersistence = $4;
n->aliases = $9;
n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, $13);
n->onconflict = PG_REPLACE_ON_CONFLICT;
n->options = $11;
n->withCheckOption = $14;
if (n->withCheckOption != PG_NO_CHECK_OPTION)
ereport(ERROR,
(errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("WITH CHECK OPTION not supported on recursive views"),
parser_errposition(@14)));
$$ = (PGNode *) n;
}
;
opt_check_option:
WITH CHECK_P OPTION { $$ = CASCADED_CHECK_OPTION; }
| WITH CASCADED CHECK_P OPTION { $$ = CASCADED_CHECK_OPTION; }
| WITH LOCAL CHECK_P OPTION { $$ = PG_LOCAL_CHECK_OPTION; }
| /* EMPTY */ { $$ = PG_NO_CHECK_OPTION; }
;

View File

@@ -0,0 +1,4 @@
%type <list> SeqOptList
%type <value> NumericOnly
%type <defelt> SeqOptElem
%type <ival> SignedIconst

View File

@@ -0,0 +1,13 @@
%type <list> alter_identity_column_option_list
%type <node> alter_column_default
%type <defelt> alter_identity_column_option
%type <list> alter_generic_option_list
%type <node> alter_table_cmd
%type <node> alter_using
%type <defelt> alter_generic_option_elem
%type <list> alter_table_cmds
%type <list> alter_generic_options
%type <ival> opt_set_data
%type <list> qualifiedColumnDef qualify_list qualified_column
%type <str> qualify_el

View File

@@ -0,0 +1,6 @@
%type <str> opt_database_alias
%type <list> ident_list ident_name
%type <node> generic_opt_arg
%type <list> generic_opt_list opt_attach_options
%type <defelt> generic_opt_elem

View File

@@ -0,0 +1 @@
%type <str> opt_col_id

View File

@@ -0,0 +1,2 @@
%type <node> comment_value
%type <objtype> comment_on_type_any_name

View File

@@ -0,0 +1,7 @@
%type <range> qualified_name
%type <str> Sconst ColId ColLabel ColIdOrString
%type <keyword> unreserved_keyword reserved_keyword other_keyword
%type <list> indirection
%type <keyword> col_name_keyword
%type <node> indirection_el
%type <str> attr_name

View File

@@ -0,0 +1,13 @@
%type <boolean> copy_from
%type <defelt> copy_delimiter
%type <list> copy_generic_opt_arg_list
%type <ival> opt_as
%type <boolean> opt_program
%type <list> copy_options
%type <defelt> opt_oids
%type <list> copy_opt_list
%type <defelt> opt_binary
%type <defelt> copy_opt_item
%type <node> copy_generic_opt_arg_list_item
%type <node> copy_file_name
%type <conststr> copy_database_flag

View File

@@ -0,0 +1,44 @@
%type <ival> ConstraintAttributeSpec
%type <node> def_arg
%type <list> OptParenthesizedSeqOptList
%type <node> generic_option_arg
%type <ival> key_action
%type <node> ColConstraint
%type <node> ColConstraintElem
%type <defelt> generic_option_elem
%type <ival> key_update
%type <ival> key_actions
%type <oncommit> OnCommitOption
%type <list> reloptions
%type <boolean> opt_no_inherit
%type <node> TableConstraint
%type <ival> TableLikeOption
%type <list> reloption_list
%type <str> ExistingIndex
%type <node> ConstraintAttr
%type <list> OptWith
%type <list> definition
%type <ival> TableLikeOptionList
%type <str> generic_option_name
%type <ival> ConstraintAttributeElem
%type <node> columnDef regularColumnDef generatedColumnDef
%type <list> def_list
%type <str> index_name
%type <node> TableElement
%type <defelt> def_elem
%type <list> opt_definition
%type <list> OptTableElementList
%type <node> columnElem
%type <list> opt_column_list
%type <list> ColQualList
%type <ival> key_delete
%type <defelt> reloption_elem
%type <list> columnList columnList_opt_comma
%type <typnam> func_type
%type <constr> GeneratedColumnType opt_GeneratedColumnType
%type <node> ConstraintElem GeneratedConstraintElem
%type <list> TableElementList
%type <ival> key_match
%type <node> TableLikeClause
%type <ival> OptTemp
%type <ival> generated_when

View File

@@ -0,0 +1,2 @@
%type <boolean> opt_with_data
%type <into> create_as_target

View File

@@ -0,0 +1,5 @@
%type <list> param_list
%type <node> macro_definition table_macro_definition table_macro_definition_parens
%type <list> macro_definition_list table_macro_list table_macro_list_internal
%type <list> MacroParameterList
%type <node> MacroParameter

View File

@@ -0,0 +1,2 @@
%type <list> OptSchemaEltList
%type <node> schema_stmt

View File

@@ -0,0 +1,4 @@
%type <str> opt_secret_name opt_persist opt_storage_specifier
%type <node> create_secret_generic_opt_arg
%type <list> create_secret_generic_opt_list
%type <defelt> create_secret_generic_opt_elem

View File

@@ -0,0 +1 @@
%type <list> OptSeqOptList

View File

@@ -0,0 +1,3 @@
%type <list> opt_enum_val_list
%type <list> enum_val_list
%type <node> create_type_value

View File

@@ -0,0 +1,3 @@
%type <range> relation_expr_opt_alias
%type <node> where_or_current_clause
%type <list> using_clause

View File

@@ -0,0 +1,6 @@
%type <objtype> drop_type_any_name
%type <objtype> drop_type_name
%type <list> any_name_list
%type <dbehavior> opt_drop_behavior
%type <objtype> drop_type_name_on_any_name
%type <list> type_name_list

View File

@@ -0,0 +1 @@
%type <str> opt_storage_drop_specifier

View File

@@ -0,0 +1,3 @@
%type <list> execute_param_clause
%type <list> execute_param_list
%type <node> execute_param_expr

View File

@@ -0,0 +1,9 @@
%type <boolean> opt_verbose
%type <node> explain_option_arg
%type <node> ExplainableStmt
%type <str> NonReservedWord
%type <str> NonReservedWord_or_Sconst
%type <list> explain_option_list
%type <str> opt_boolean_or_string
%type <defelt> explain_option_elem
%type <str> explain_option_name

View File

@@ -0,0 +1,6 @@
%type <str> access_method
%type <str> access_method_clause
%type <boolean> opt_concurrently
%type <str> opt_index_name
%type <list> opt_reloptions
%type <boolean> opt_unique

View File

@@ -0,0 +1,19 @@
%type <istmt> insert_rest
%type <range> insert_target
%type <infer> opt_conf_expr
%type <with> opt_with_clause
%type <target> insert_column_item
%type <list> set_clause
%type <onconflict> opt_on_conflict
%type <onconflictshorthand> opt_or_action
%type <bynameorposition> opt_by_name_or_position
%type <ielem> index_elem
%type <list> returning_clause
%type <override> override_kind
%type <list> set_target_list
%type <list> opt_collate
%type <list> opt_class
%type <list> insert_column_list
%type <list> set_clause_list set_clause_list_opt_comma
%type <list> index_params
%type <target> set_target

View File

@@ -0,0 +1,3 @@
%type <str> file_name
%type <str> opt_ext_version
%type <loadinstalltype> opt_force

View File

@@ -0,0 +1,4 @@
%type <list> merge_match_list opt_insert_column_list
%type <node> matched_or_not_matched_clause matched_clause not_matched_clause opt_and_clause matched_clause_action opt_star_expr opt_error_message
%type <mergeaction> opt_source_or_target

View File

@@ -0,0 +1,2 @@
%type <list> prep_type_clause
%type <node> PreparableStmt

View File

@@ -0,0 +1 @@
%type <ival> opt_column

View File

@@ -0,0 +1,134 @@
%type <node> select_no_parens select_with_parens select_clause
simple_select values_clause values_clause_opt_comma
%type <sortorder> opt_asc_desc
%type <nullorder> opt_nulls_order
%type <ignorenulls> opt_ignore_nulls
%type <node> opt_collate_clause
%type <node> indirection_expr indirection_expr_or_a_expr
%type <node> struct_expr list_expr map_expr param_expr sample_value
%type <lockwaitpolicy> opt_nowait_or_skip
%type <str> name
%type <list> func_name qual_Op qual_all_Op subquery_Op
%type <str> all_Op
%type <conststr> MathOp
%type <list> distinct_clause opt_all_clause name_list_opt_comma opt_name_list name_list_opt_comma_opt_bracket opt_on_key column_ref_list_opt_comma column_ref_list
sort_clause opt_sort_clause sortby_list name_list from_clause from_list from_list_opt_comma opt_array_bounds
qualified_name_list any_name any_operator expr_list attrs expr_list_opt_comma opt_expr_list_opt_comma c_expr_list c_expr_list_opt_comma
target_list opt_indirection target_list_opt_comma opt_target_list_opt_comma
group_clause select_limit
opt_select_limit TableFuncElementList opt_type_modifiers opt_select extended_indirection opt_extended_indirection
qualified_typename
%type <list> group_by_list group_by_list_opt_comma opt_func_arguments unpivot_header
%type <node> group_by_item empty_grouping_set rollup_clause cube_clause grouping_sets_clause grouping_or_grouping_id
%type <range> OptTempTableName
%type <into> into_clause
%type <lockstrength> for_locking_strength
%type <node> for_locking_item
%type <list> for_locking_clause opt_for_locking_clause for_locking_items
%type <list> locked_rels_list
%type <boolean> all_or_distinct
%type <node> join_outer join_qual
%type <jtype> join_type
%type <list> extract_list overlay_list position_list
%type <list> substr_list trim_list
%type <list> opt_interval
%type <node> overlay_placing substr_from substr_for
%type <list> except_list opt_except_list replace_list_el replace_list opt_replace_list replace_list_opt_comma
%type <list> rename_list_el rename_list rename_list_opt_comma opt_rename_list
%type <list> except_name except_name_list except_name_list_opt_comma
%type <node> limit_clause select_limit_value
offset_clause select_offset_value
select_fetch_first_value I_or_F_const
%type <ival> row_or_rows first_or_next
%type <node> TableFuncElement
%type <list> columnrefList
%type <node> where_clause a_expr b_expr c_expr d_expr AexprConst opt_slice_bound extended_indirection_el
columnref columnref_opt_indirection in_expr having_clause qualify_clause func_table opt_at_clause at_specifier
%type <list> rowsfrom_item rowsfrom_list opt_col_def_list
%type <boolean> opt_ordinality
%type <list> func_arg_list
%type <node> func_arg_expr
%type <node> list_comprehension
%type <list> row qualified_row type_list colid_type_list
%type <node> case_expr case_arg when_clause case_default
%type <list> when_clause_list
%type <subquerytype> sub_type
%type <node> dict_arg
%type <list> dict_arguments dict_arguments_opt_comma
%type <list> map_arg map_arguments map_arguments_opt_comma opt_map_arguments_opt_comma
%type <alias> alias_clause opt_alias_clause alias_prefix_colon_clause
%type <list> func_alias_clause
%type <sortby> sortby
%type <node> table_ref
%type <jexpr> joined_table
%type <range> relation_expr
%type <node> tablesample_clause opt_tablesample_clause tablesample_entry
%type <node> sample_clause sample_count
%type <str> opt_sample_func at_unit
%type <ival> opt_repeatable_clause
%type <target> target_el
%type <typnam> Typename SimpleTypename ConstTypename opt_Typename
GenericType Numeric opt_float
Character ConstCharacter
CharacterWithLength CharacterWithoutLength
ConstDatetime ConstInterval
Bit ConstBit BitWithLength BitWithoutLength
%type <conststr> character
%type <str> extract_arg
%type <boolean> opt_varying opt_timezone
%type <ival> Iconst
%type <str> type_function_name param_name type_name_token function_name_token
%type <str> ColLabelOrString
%type <keyword> type_func_name_keyword type_name_keyword func_name_keyword
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
%type <node> common_table_expr
%type <with> with_clause
%type <list> cte_list
%type <ctematerialize> opt_materialized
%type <list> within_group_clause
%type <node> filter_clause
%type <boolean> export_clause
%type <list> window_clause window_definition_list opt_partition_clause
%type <windef> window_definition over_clause window_specification
opt_frame_clause frame_extent frame_bound
%type <ival> opt_window_exclusion_clause
%type <str> opt_existing_window_name
%type <node> pivot_value pivot_column_entry single_pivot_value unpivot_value
%type <list> pivot_value_list pivot_column_list_internal pivot_column_list pivot_header opt_pivot_group_by unpivot_value_list
%type <boolean> opt_include_nulls

View File

@@ -0,0 +1 @@
%type <transactiontype> opt_transaction_type

View File

@@ -0,0 +1,4 @@
%type <ival> vacuum_option_elem
%type <boolean> opt_full
%type <ival> vacuum_option_list
%type <boolean> opt_freeze

View File

@@ -0,0 +1,2 @@
%type <vsetstmt> generic_reset
%type <vsetstmt> reset_rest

View File

@@ -0,0 +1,5 @@
%type <vsetstmt> set_rest
%type <vsetstmt> generic_set
%type <node> var_value
%type <node> zone_value
%type <list> var_list

View File

@@ -0,0 +1 @@
%type <str> var_name

View File

@@ -0,0 +1 @@
%type <viewcheckoption> opt_check_option