Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
postgres-lambda-diff
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jakob Huber
postgres-lambda-diff
Commits
9cad9feb
Commit
9cad9feb
authored
26 years ago
by
Bruce Momjian
Browse files
Options
Downloads
Patches
Plain Diff
cleanup
parent
985f4ab9
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/backend/parser/README
+1
-1
1 addition, 1 deletion
src/backend/parser/README
src/backend/parser/parse_target.c
+149
-150
149 additions, 150 deletions
src/backend/parser/parse_target.c
with
150 additions
and
151 deletions
src/backend/parser/README
+
1
−
1
View file @
9cad9feb
...
...
@@ -9,11 +9,11 @@ keywords.c turn keywords into specific tokens
gram.y parse the tokens and fill query-type-specific structures
analyze.c handle post-parse processing for each query type
parse_clause.c handle clauses like WHERE, ORDER BY, GROUP BY, ...
parse_coerce.c used for coercing expressions of different types
parse_expr.c handle expressions like col, col + 3, x = 3 or x = 4
parse_oper.c handle operations in expressions
parse_agg.c handle aggregates, like SUM(col1), AVG(col2), ...
parse_func.c handle functions, table.column and column identifiers
parse_node.c create nodes for various structures
parse_target.c handle the result list of the query
parse_relation.c support routines for tables and column handling
...
...
This diff is collapsed.
Click to expand it.
src/backend/parser/parse_target.c
+
149
−
150
View file @
9cad9feb
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.2
1
1998/08/
19 02:02:2
6 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.2
2
1998/08/
23 14:43:4
6 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -187,6 +187,154 @@ printf("transformTargetIdent- attrtype_target = %d; type_mod = %d\n", attrtype_t
}
/* transformTargetIdent() */
/* MakeTargetlistExpr()
* Make a TargetEntry from an expression.
* arrayRef is a list of transformed A_Indices.
*
* For type mismatches between expressions and targets, use the same
* techniques as for function and operator type coersion.
* - thomas 1998-05-08
*
* Added resjunk flag and made extern so that it can be use by GROUP/
* ORDER BY a function or expersion not in the target_list
* - daveh@insightdist.com 1998-07-31
*/
TargetEntry
*
MakeTargetlistExpr
(
ParseState
*
pstate
,
char
*
colname
,
Node
*
expr
,
List
*
arrayRef
,
int16
resjunk
)
{
Oid
type_id
,
attrtype
;
int32
type_mod
,
attrtypmod
;
int
resdomno
;
Relation
rd
;
bool
attrisset
;
TargetEntry
*
tent
;
Resdom
*
resnode
;
if
(
expr
==
NULL
)
elog
(
ERROR
,
"MakeTargetlistExpr: invalid use of NULL expression"
);
type_id
=
exprType
(
expr
);
if
(
nodeTag
(
expr
)
==
T_Var
)
type_mod
=
((
Var
*
)
expr
)
->
vartypmod
;
else
type_mod
=
-
1
;
/* Processes target columns that will be receiving results */
if
(
pstate
->
p_is_insert
||
pstate
->
p_is_update
)
{
/*
* insert or update query -- insert, update work only on one
* relation, so multiple occurence of same resdomno is bogus
*/
rd
=
pstate
->
p_target_relation
;
Assert
(
rd
!=
NULL
);
resdomno
=
attnameAttNum
(
rd
,
colname
);
attrisset
=
attnameIsSet
(
rd
,
colname
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
if
((
arrayRef
!=
NIL
)
&&
(
lfirst
(
arrayRef
)
==
NIL
))
attrtype
=
GetArrayElementType
(
attrtype
);
attrtypmod
=
rd
->
rd_att
->
attrs
[
resdomno
-
1
]
->
atttypmod
;
/* Check for InvalidOid since that seems to indicate a NULL constant... */
if
(
type_id
!=
InvalidOid
)
{
/* Mismatch on types? then try to coerce to target... */
if
(
attrtype
!=
type_id
)
{
Oid
typelem
;
if
(
arrayRef
&&
!
(((
A_Indices
*
)
lfirst
(
arrayRef
))
->
lidx
))
typelem
=
typeidTypElem
(
attrtype
);
else
typelem
=
attrtype
;
expr
=
CoerceTargetExpr
(
pstate
,
expr
,
type_id
,
typelem
);
if
(
!
HeapTupleIsValid
(
expr
))
elog
(
ERROR
,
"parser: attribute '%s' is of type '%s'"
" but expression is of type '%s'"
"
\n\t
You will need to rewrite or cast the expression"
,
colname
,
typeidTypeName
(
attrtype
),
typeidTypeName
(
type_id
));
}
#ifdef PARSEDEBUG
printf
(
"MakeTargetlistExpr: attrtypmod is %d
\n
"
,
(
int4
)
attrtypmod
);
#endif
/* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
if
(
attrtypmod
>
0
)
expr
=
SizeTargetExpr
(
pstate
,
expr
,
attrtype
,
attrtypmod
);
}
if
(
arrayRef
!=
NIL
)
{
Expr
*
target_expr
;
Attr
*
att
=
makeNode
(
Attr
);
List
*
ar
=
arrayRef
;
List
*
upperIndexpr
=
NIL
;
List
*
lowerIndexpr
=
NIL
;
att
->
relname
=
pstrdup
(
RelationGetRelationName
(
rd
)
->
data
);
att
->
attrs
=
lcons
(
makeString
(
colname
),
NIL
);
target_expr
=
(
Expr
*
)
ParseNestedFuncOrColumn
(
pstate
,
att
,
&
pstate
->
p_last_resno
,
EXPR_COLUMN_FIRST
);
while
(
ar
!=
NIL
)
{
A_Indices
*
ind
=
lfirst
(
ar
);
if
(
lowerIndexpr
||
(
!
upperIndexpr
&&
ind
->
lidx
))
{
/*
* XXX assume all lowerIndexpr is non-null in this
* case
*/
lowerIndexpr
=
lappend
(
lowerIndexpr
,
ind
->
lidx
);
}
upperIndexpr
=
lappend
(
upperIndexpr
,
ind
->
uidx
);
ar
=
lnext
(
ar
);
}
expr
=
(
Node
*
)
make_array_set
(
target_expr
,
upperIndexpr
,
lowerIndexpr
,
(
Expr
*
)
expr
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
attrtypmod
=
get_atttypmod
(
RelationGetRelid
(
rd
),
resdomno
);
}
}
else
{
resdomno
=
pstate
->
p_last_resno
++
;
attrtype
=
type_id
;
attrtypmod
=
type_mod
;
}
resnode
=
makeResdom
((
AttrNumber
)
resdomno
,
(
Oid
)
attrtype
,
attrtypmod
,
colname
,
(
Index
)
0
,
(
Oid
)
0
,
resjunk
);
tent
=
makeTargetEntry
(
resnode
,
expr
);
return
tent
;
}
/* MakeTargetlistExpr() */
/* transformTargetList()
* Turns a list of ResTarget's into a list of TargetEntry's.
*/
...
...
@@ -299,7 +447,6 @@ printf("transformTargetList: decode T_Expr\n");
/* this is not an array assignment */
if
(
colname
==
NULL
)
{
/*
* if you're wondering why this is here, look
* at the yacc grammar for why a name can be
...
...
@@ -559,154 +706,6 @@ printf("SizeTargetExpr: no conversion function for sizing\n");
}
/* SizeTargetExpr() */
/* MakeTargetlistExpr()
* Make a TargetEntry from an expression.
* arrayRef is a list of transformed A_Indices.
*
* For type mismatches between expressions and targets, use the same
* techniques as for function and operator type coersion.
* - thomas 1998-05-08
*
* Added resjunk flag and made extern so that it can be use by GROUP/
* ORDER BY a function or expersion not in the target_list
* - daveh@insightdist.com 1998-07-31
*/
TargetEntry
*
MakeTargetlistExpr
(
ParseState
*
pstate
,
char
*
colname
,
Node
*
expr
,
List
*
arrayRef
,
int16
resjunk
)
{
Oid
type_id
,
attrtype
;
int32
type_mod
,
attrtypmod
;
int
resdomno
;
Relation
rd
;
bool
attrisset
;
TargetEntry
*
tent
;
Resdom
*
resnode
;
if
(
expr
==
NULL
)
elog
(
ERROR
,
"MakeTargetlistExpr: invalid use of NULL expression"
);
type_id
=
exprType
(
expr
);
if
(
nodeTag
(
expr
)
==
T_Var
)
type_mod
=
((
Var
*
)
expr
)
->
vartypmod
;
else
type_mod
=
-
1
;
/* Processes target columns that will be receiving results */
if
(
pstate
->
p_is_insert
||
pstate
->
p_is_update
)
{
/*
* insert or update query -- insert, update work only on one
* relation, so multiple occurence of same resdomno is bogus
*/
rd
=
pstate
->
p_target_relation
;
Assert
(
rd
!=
NULL
);
resdomno
=
attnameAttNum
(
rd
,
colname
);
attrisset
=
attnameIsSet
(
rd
,
colname
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
if
((
arrayRef
!=
NIL
)
&&
(
lfirst
(
arrayRef
)
==
NIL
))
attrtype
=
GetArrayElementType
(
attrtype
);
attrtypmod
=
rd
->
rd_att
->
attrs
[
resdomno
-
1
]
->
atttypmod
;
/* Check for InvalidOid since that seems to indicate a NULL constant... */
if
(
type_id
!=
InvalidOid
)
{
/* Mismatch on types? then try to coerce to target... */
if
(
attrtype
!=
type_id
)
{
Oid
typelem
;
if
(
arrayRef
&&
!
(((
A_Indices
*
)
lfirst
(
arrayRef
))
->
lidx
))
typelem
=
typeidTypElem
(
attrtype
);
else
typelem
=
attrtype
;
expr
=
CoerceTargetExpr
(
pstate
,
expr
,
type_id
,
typelem
);
if
(
!
HeapTupleIsValid
(
expr
))
elog
(
ERROR
,
"parser: attribute '%s' is of type '%s'"
" but expression is of type '%s'"
"
\n\t
You will need to rewrite or cast the expression"
,
colname
,
typeidTypeName
(
attrtype
),
typeidTypeName
(
type_id
));
}
#ifdef PARSEDEBUG
printf
(
"MakeTargetlistExpr: attrtypmod is %d
\n
"
,
(
int4
)
attrtypmod
);
#endif
/* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
if
(
attrtypmod
>
0
)
expr
=
SizeTargetExpr
(
pstate
,
expr
,
attrtype
,
attrtypmod
);
}
if
(
arrayRef
!=
NIL
)
{
Expr
*
target_expr
;
Attr
*
att
=
makeNode
(
Attr
);
List
*
ar
=
arrayRef
;
List
*
upperIndexpr
=
NIL
;
List
*
lowerIndexpr
=
NIL
;
att
->
relname
=
pstrdup
(
RelationGetRelationName
(
rd
)
->
data
);
att
->
attrs
=
lcons
(
makeString
(
colname
),
NIL
);
target_expr
=
(
Expr
*
)
ParseNestedFuncOrColumn
(
pstate
,
att
,
&
pstate
->
p_last_resno
,
EXPR_COLUMN_FIRST
);
while
(
ar
!=
NIL
)
{
A_Indices
*
ind
=
lfirst
(
ar
);
if
(
lowerIndexpr
||
(
!
upperIndexpr
&&
ind
->
lidx
))
{
/*
* XXX assume all lowerIndexpr is non-null in this
* case
*/
lowerIndexpr
=
lappend
(
lowerIndexpr
,
ind
->
lidx
);
}
upperIndexpr
=
lappend
(
upperIndexpr
,
ind
->
uidx
);
ar
=
lnext
(
ar
);
}
expr
=
(
Node
*
)
make_array_set
(
target_expr
,
upperIndexpr
,
lowerIndexpr
,
(
Expr
*
)
expr
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
attrtypmod
=
get_atttypmod
(
RelationGetRelid
(
rd
),
resdomno
);
}
}
else
{
resdomno
=
pstate
->
p_last_resno
++
;
attrtype
=
type_id
;
attrtypmod
=
type_mod
;
}
resnode
=
makeResdom
((
AttrNumber
)
resdomno
,
(
Oid
)
attrtype
,
attrtypmod
,
colname
,
(
Index
)
0
,
(
Oid
)
0
,
resjunk
);
tent
=
makeTargetEntry
(
resnode
,
expr
);
return
tent
;
}
/* MakeTargetlistExpr() */
/*
* makeTargetNames -
* generate a list of column names if not supplied or
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment