with supporting code.
Creates SubLink node in gram.y.
psql.c patch for newatttypmod field.
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.31 1998/01/16 23:19:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.32 1998/01/17 04:53:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
return newnode;
}
+/* ----------------
+ * _copySubLink
+ * ----------------
+ */
+static SubLink *
+_copySubLink(SubLink *from)
+{
+ SubLink *newnode = makeNode(SubLink);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->subLinkType = from->subLinkType;
+ newnode->useor = from->useor;
+ Node_Copy(from, newnode, lefthand);
+ Node_Copy(from, newnode, oper);
+ Node_Copy(from, newnode, subselect);
+
+ return newnode;
+}
+
static Array *
_copyArray(Array *from)
{
Node_Copy(from, newnode, havingQual);
newnode->hasAggs = from->hasAggs;
+ newnode->hasSubLinks = from->hasSubLinks;
if (from->unionClause)
{
case T_Aggreg:
retval = _copyAggreg(from);
break;
+ case T_SubLink:
+ retval = _copySubLink(from);
+ break;
/*
* RELATION NODES
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.22 1998/01/16 23:19:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.23 1998/01/17 04:53:09 momjian Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
_outNode(str, node->havingQual);
appendStringInfo(str, " :hasAggs ");
appendStringInfo(str, (node->hasAggs ? "true" : "false"));
+ appendStringInfo(str, " :hasSubLinks ");
+ appendStringInfo(str, (node->hasSubLinks ? "true" : "false"));
appendStringInfo(str, " :unionClause ");
_outNode(str, node->unionClause);
}
appendStringInfo(str, node->usenulls ? "true" : "false");
}
+/*
+ * SubLink
+ */
+static void
+_outSubLink(StringInfo str, SubLink *node)
+{
+ char buf[500];
+
+ appendStringInfo(str, "SUBLINK");
+ sprintf(buf, " :subLinkType %d ", node->subLinkType);
+ appendStringInfo(str, buf);
+ appendStringInfo(str, " :useor ");
+ appendStringInfo(str, node->useor ? "true" : "false");
+ appendStringInfo(str, " :lefthand ");
+ _outNode(str, node->lefthand);
+ appendStringInfo(str, " :oper ");
+ _outNode(str, node->oper);
+ appendStringInfo(str, " :subselect ");
+ _outNode(str, node->subselect);
+}
+
/*
* Array is a subclass of Expr
*/
case T_Aggreg:
_outAggreg(str, obj);
break;
+ case T_SubLink:
+ _outSubLink(str, obj);
+ break;
case T_Array:
_outArray(str, obj);
break;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.18 1998/01/15 18:59:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.19 1998/01/17 04:53:11 momjian Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
token = lsptok(NULL, &length); /* get hasAggs */
local_node->hasAggs = (token[0] == 't') ? true : false;
+ token = lsptok(NULL, &length); /* skip the :hasSubLinks */
+ token = lsptok(NULL, &length); /* get hasSubLinks */
+ local_node->hasSubLinks = (token[0] == 't') ? true : false;
+
token = lsptok(NULL, &length); /* skip :unionClause */
local_node->unionClause = nodeRead(true);
return (local_node);
}
+/* ----------------
+ * _readSubLink
+ *
+ * SubLink is a subclass of Node
+ * ----------------
+ */
+static SubLink *
+_readSubLink()
+{
+ SubLink *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(SubLink);
+
+ token = lsptok(NULL, &length); /* eat :subLinkType */
+ token = lsptok(NULL, &length); /* get subLinkType */
+ local_node->subLinkType = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :useor */
+ token = lsptok(NULL, &length); /* get useor */
+ local_node->useor = (token[0] == 't') ? true : false;
+
+ token = lsptok(NULL, &length); /* eat :lefthand */
+ local_node->lefthand = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :oper */
+ local_node->oper = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :subselect */
+ local_node->subselect = nodeRead(true); /* now read it */
+
+ return (local_node);
+}
+
/*
* Stuff from execnodes.h
*/
{
return_value = _readAggreg();
}
+ else if (!strncmp(token, "SUBLINK", 6))
+ {
+ return_value = _readSubLink();
+ }
else if (!strncmp(token, "AGG", 3))
{
return_value = _readAgg();
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.91 1998/01/16 23:20:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.92 1998/01/17 04:53:16 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
static char *xlateSqlType(char *);
static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
-static Node *makeRowExpr(char *opr, List *largs, List *rargs);
void mapTargetColumns(List *source, List *target);
static List *makeConstantList( A_Const *node);
static char *FlattenStringList(List *list);
$$->unique = NULL;
$$->targetList = $3;
$$->fromClause = NIL;
- $$->whereClause = NIL;
+ $$->whereClause = NULL;
$$->groupClause = NIL;
- $$->havingClause = NIL;
+ $$->havingClause = NULL;
$$->unionClause = NIL;
}
| SELECT opt_unique res_target_list2
*/
row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
{
- $$ = NULL;
+ SubLink *n = makeNode(SubLink);
+ n->lefthand = $2;
+ n->subLinkType = IN_SUBLINK;
+ n->subselect = $6;
+ $$ = (Node *)n;
}
| '(' row_descriptor ')' NOT IN '(' SubSelect ')'
{
- $$ = NULL;
- }
- | '(' row_descriptor ')' '=' '(' row_descriptor ')'
- {
- $$ = makeRowExpr("=", $2, $6);
- }
- | '(' row_descriptor ')' '<' '(' row_descriptor ')'
- {
- $$ = makeRowExpr("<", $2, $6);
+ SubLink *n = makeNode(SubLink);
+ n->lefthand = $2;
+ n->subLinkType = NOTIN_SUBLINK;
+ n->subselect = $7;
+ $$ = (Node *)n;
}
- | '(' row_descriptor ')' '>' '(' row_descriptor ')'
+/* We accept all Operators? */
+ | '(' row_descriptor ')' Op '(' SubSelect ')'
{
- $$ = makeRowExpr("<", $2, $6);
+ SubLink *n = makeNode(SubLink);
+ n->lefthand = $2;
+ n->subLinkType = OPER_SUBLINK;
+ n->oper = lcons($4, NIL);
+ n->subselect = $6;
+ $$ = (Node *)n;
}
+/* Do we need this?
| '(' row_descriptor ')' Op '(' row_descriptor ')'
{
- $$ = makeRowExpr($4, $2, $6);
+ SubLink *n = makeNode(SubLink);
+ n->lefthand = $2;
+ n->subLinkType = OPER_SUBLINK;
+ n->oper = lcons($4, NIL);
+ n->subselect = $6;
+ $$ = (Node *)n;
}
+*/
;
row_descriptor: row_list ',' a_expr
*/
| EXISTS '(' SubSelect ')'
{
- elog(ERROR,"EXISTS not yet implemented");
- $$ = $3;
+ SubLink *n = makeNode(SubLink);
+ n->lefthand = NIL;
+ n->subLinkType = EXISTS_SUBLINK;
+ n->oper = NIL;
+ n->subselect = $3;
+ $$ = (Node *)n;
}
| EXTRACT '(' extract_list ')'
{
makeA_Expr(OP, ">", $1, $6));
}
| a_expr IN { saved_In_Expr = $1; } '(' in_expr ')'
- { $$ = $5; }
+ {
+ if (nodeTag($5) == T_SubLink)
+ {
+ ((SubLink *)$5)->lefthand = lcons($1, NIL);
+ ((SubLink *)$5)->subLinkType = IN_SUBLINK;
+ $$ = (Node *)$5;
+ }
+ else $$ = $5;
+ }
| a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr ')'
- { $$ = $6; }
+ {
+ if (nodeTag($6) == T_SubLink)
+ {
+ ((SubLink *)$6)->lefthand = lcons($1, NIL);
+ ((SubLink *)$6)->subLinkType = NOTIN_SUBLINK;
+ $$ = (Node *)$6;
+ }
+ else $$ = $6;
+ }
| a_expr AND a_expr
{ $$ = makeA_Expr(AND, NULL, $1, $3); }
| a_expr OR a_expr
in_expr: SubSelect
{
- elog(ERROR,"IN (SUBSELECT) not yet implemented");
- $$ = $1;
+ SubLink *n = makeNode(SubLink);
+ n->subselect = $1;
+ $$ = (Node *)n;
}
| in_expr_nodes
{ $$ = $1; }
not_in_expr: SubSelect
{
- elog(ERROR,"NOT IN (SUBSELECT) not yet implemented");
- $$ = $1;
+ SubLink *n = makeNode(SubLink);
+ n->subselect = $1;
+ $$ = (Node *)n;
}
| not_in_expr_nodes
{ $$ = $1; }
return (Node *)a;
}
-/* makeRowExpr()
- * Generate separate operator nodes for a single row descriptor expression.
- * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
- */
-static Node *
-makeRowExpr(char *opr, List *largs, List *rargs)
-{
- Node *expr = NULL;
- Node *larg, *rarg;
-
- if (length(largs) != length(rargs))
- elog(ERROR,"Unequal number of entries in row expression");
-
- if (lnext(largs) != NIL)
- expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
-
- larg = lfirst(largs);
- rarg = lfirst(rargs);
-
- if ((strcmp(opr, "=") == 0)
- || (strcmp(opr, "<") == 0)
- || (strcmp(opr, "<=") == 0)
- || (strcmp(opr, ">") == 0)
- || (strcmp(opr, ">=") == 0))
- {
- if (expr == NULL)
- expr = makeA_Expr(OP, opr, larg, rarg);
- else
- expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
- }
- else if (strcmp(opr, "<>") == 0)
- {
- if (expr == NULL)
- expr = makeA_Expr(OP, opr, larg, rarg);
- else
- expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
- }
- else
- {
- elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
- }
-
-#if FALSE
- while ((largs != NIL) && (rargs != NIL))
- {
- larg = lfirst(largs);
- rarg = lfirst(rargs);
-
- if (expr == NULL)
- expr = makeA_Expr(OP, opr, larg, rarg);
- else
- expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
-
- largs = lnext(largs);
- rargs = lnext(rargs);
- }
- pprint(expr);
-#endif
-
- return expr;
-} /* makeRowExpr() */
-
void
mapTargetColumns(List *src, List *dst)
{
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.6 1998/01/15 19:00:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.7 1998/01/17 04:53:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
ParseState *pstate;
pstate = palloc(sizeof(ParseState));
+ MemSet(pstate, 0, sizeof(ParseState));
+
pstate->p_last_resno = 1;
- pstate->p_rtable = NIL;
- pstate->p_hasAggs = false;
- pstate->p_is_insert = false;
- pstate->p_insert_columns = NIL;
- pstate->p_is_update = false;
- pstate->p_is_rule = false;
- pstate->p_in_where_clause = false;
- pstate->p_target_relation = NULL;
- pstate->p_target_rangetblentry = NULL;
return (pstate);
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.125 1998/01/09 19:34:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.126 1998/01/17 04:53:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
char *rnotnull;
char *rhasdef;
int i;
- int rsize;
+ int attlen, atttypmod;
PGresult *res, *res2;
int usePipe = 0;
char *pagerenv;
}
descbuf[0] = '\0';
- strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull, a.atthasdef ");
+ strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, ");
+ strcat(descbuf, "a.atttypmod, a.attnotnull, a.atthasdef ");
strcat(descbuf, "FROM pg_class c, pg_attribute a, pg_type t ");
strcat(descbuf, "WHERE c.relname = '");
strcat(descbuf, table);
fprintf(fout,"| %-32.32s | ", PQgetvalue(res, i, 1));
rtype = PQgetvalue(res, i, 2);
- rsize = atoi(PQgetvalue(res, i, 3));
- rnotnull = PQgetvalue(res, i, 4);
- rhasdef = PQgetvalue(res, i, 5);
+ attlen = atoi(PQgetvalue(res, i, 3));
+ atttypmod = atoi(PQgetvalue(res, i, 4));
+ rnotnull = PQgetvalue(res, i, 5);
+ rhasdef = PQgetvalue(res, i, 6);
strcpy(type_str, rtype);
if (strcmp(rtype, "bpchar") == 0)
fprintf(fout,"%6s |", "var");
else if (strcmp(rtype, "bpchar") == 0 ||
strcmp(rtype, "varchar") == 0)
- fprintf(fout,"%6i |", rsize > 0 ? rsize - VARHDRSZ : 0);
+ fprintf(fout,"%6i |", atttypmod > 0 ? atttypmod - VARHDRSZ : 0);
else
{
- if (rsize > 0)
- fprintf(fout,"%6i |", rsize);
+ if (attlen > 0)
+ fprintf(fout,"%6i |", attlen);
else
fprintf(fout,"%6s |", "var");
}
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodes.h,v 1.22 1998/01/10 04:30:08 momjian Exp $
+ * $Id: nodes.h,v 1.23 1998/01/17 04:53:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
T_Const,
T_Param,
T_Aggreg,
+ T_SubLink,
T_Func,
T_Array,
T_ArrayRef,
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.45 1998/01/16 23:20:55 momjian Exp $
+ * $Id: parsenodes.h,v 1.46 1998/01/17 04:53:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
bool isBinary; /* binary portal? */
bool unionall; /* union without unique sort */
bool hasAggs; /* has aggregates in target list */
+ bool hasSubLinks; /* has subquery SubLink */
char *uniqueFlag; /* NULL, '*', or Unique attribute name */
List *sortClause; /* a list of SortClause's */
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: primnodes.h,v 1.12 1998/01/04 04:31:37 momjian Exp $
+ * $Id: primnodes.h,v 1.13 1998/01/17 04:53:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
bool usenulls;
} Aggreg;
+/* ----------------
+ * SubLink
+ * subLinkType - EXISTS, ALL, ANY, EXPR
+ * useor - TRUE for <>
+ * lefthand - list of Var/Const nodes on the left
+ * oper - list of Oper nodes
+ * subselect - subselect as Query* or parsetree
+ * ----------------
+ */
+typedef enum SubLinkType
+{
+ EXISTS_SUBLINK, ALL_SUBLINK, ANY_SUBLINK, EXPR_SUBLINK,
+ IN_SUBLINK, NOTIN_SUBLINK, OPER_SUBLINK
+} SubLinkType;
+
+
+typedef struct SubLink
+{
+struct Query;
+ NodeTag type;
+ SubLinkType subLinkType;
+ bool useor;
+ List *lefthand;
+ List *oper;
+ Node *subselect;
+} SubLink;
+
/* ----------------
* Array
* arrayelemtype - base type of the array's elements (homogenous!)
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_node.h,v 1.4 1998/01/15 19:00:16 momjian Exp $
+ * $Id: parse_node.h,v 1.5 1998/01/17 04:53:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
List *p_rtable;
List *p_insert_columns;
bool p_hasAggs;
+ bool p_hasSubLinks;
bool p_is_insert;
bool p_is_update;
bool p_is_rule;