Lists: | pgsql-interfaces |
---|
From: | Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> |
---|---|
To: | pgsql-interfaces(at)lists(dot)postgresql(dot)org |
Cc: | Michael Meskes <meskes(at)postgresql(dot)org> |
Subject: | Host variables in ecpg |
Date: | 2018-07-24 10:46:57 |
Message-ID: | CAE9k0PmTBOFAjOzc814jWW_AcnyUqA4dLX245eLxAP3zHCirYQ@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-interfaces |
Hi All,
While trying to understand the concept of host variables in ecpg, I
came to know that the host variables in ecpg can be declared using the
following two methods,
1) Using the explicit declare section.
EXEC SQL BEGIN DECLARE SECTION;
double d = 3.14;
EXEC SQL END DECLARE SECTION;
2) Using an implicit declare section.
EXEC SQL double d = 3.14;
Incase of 1 (i.e. when using explicit declare section) the host
variables gets scanned in C state using '<C>{identifier}' rule whereas
incase of 2 (i.e. when using implicit declare section) the host
variables gets scanned in SQL state using '<SQL>{identifier}' rule. I
could observe that, in sql state, we perform SQL keyword lookup
followed by C keyword lookup. However, in case of C state, we just
perform C keyword lookup. Please refer to the following code snippets
in pgc.l file
<C>{identifier} {
const ScanKeyword *keyword;
if ((!INFORMIX_MODE || !isinformixdefine()) &&
!isdefine())
{
keyword = ScanCKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
else
{
base_yylval.str = mm_strdup(yytext);
return IDENT;
}
}
<SQL>{identifier} {
const ScanKeyword *keyword;
if (!isdefine())
{
/* Is it an SQL/ECPG keyword? */
keyword = ScanECPGKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
/* Is it a C keyword? */
keyword = ScanCKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
/*
* None of the above. Return it as an identifier.
*
* The backend will attempt to truncate
and case-fold
* the identifier, but I see no good reason for ecpg
* to do so; that's just another way that
ecpg could get
* out of step with the backend.
*/
base_yylval.str = mm_strdup(yytext);
return IDENT;
Shouldn't we perform both SQL and C table lookup in C state as well?
Let's consider the following test where a double datatype is used
inside the declare section.
EXEC SQL BEGIN DECLARE SECTION;
double d1;
EXEC SQL END DECLARE SECTION;
In above case "double" would be scanned in C state by <C>{identifiers}
rule which would search for double keyword in ScanCKeywords[] table
and since it doesn't find it, it returns some IDENT keyword for it.
However, if above is written as "EXEC SQL double d;" then, double
would be scanned in SQL state by <SQL>{identifiers} rule which would
first search for double in SQLScanKeywords[] followed by
ScanCKeywords[]. In this case, as double is declared in
SQLScanKeywords[], it would return some valid keyword for double.
--
With Regards,
Ashutosh Sharma
EnterpriseDB:http://www.enterprisedb.com
From: | Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> |
---|---|
To: | pgsql-interfaces(at)lists(dot)postgresql(dot)org |
Cc: | Michael Meskes <meskes(at)postgresql(dot)org> |
Subject: | Re: Host variables in ecpg |
Date: | 2018-07-25 05:01:16 |
Message-ID: | CAE9k0PkD+BD=XXLZ+EkticGS-r6k3OtrQYjp__fDxaqdAije4Q@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-interfaces |
On Tue, Jul 24, 2018 at 4:16 PM, Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> wrote:
> Hi All,
>
> While trying to understand the concept of host variables in ecpg, I
> came to know that the host variables in ecpg can be declared using the
> following two methods,
>
> 1) Using the explicit declare section.
>
> EXEC SQL BEGIN DECLARE SECTION;
> double d = 3.14;
> EXEC SQL END DECLARE SECTION;
>
> 2) Using an implicit declare section.
>
> EXEC SQL double d = 3.14;
>
>
> Incase of 1 (i.e. when using explicit declare section) the host
> variables gets scanned in C state using '<C>{identifier}' rule whereas
> incase of 2 (i.e. when using implicit declare section) the host
> variables gets scanned in SQL state using '<SQL>{identifier}' rule. I
> could observe that, in sql state, we perform SQL keyword lookup
> followed by C keyword lookup. However, in case of C state, we just
> perform C keyword lookup. Please refer to the following code snippets
> in pgc.l file
>
> <C>{identifier} {
> const ScanKeyword *keyword;
>
> if ((!INFORMIX_MODE || !isinformixdefine()) &&
> !isdefine())
> {
> keyword = ScanCKeywordLookup(yytext);
> if (keyword != NULL)
> return keyword->value;
> else
> {
> base_yylval.str = mm_strdup(yytext);
> return IDENT;
> }
> }
>
>
> <SQL>{identifier} {
> const ScanKeyword *keyword;
>
> if (!isdefine())
> {
> /* Is it an SQL/ECPG keyword? */
> keyword = ScanECPGKeywordLookup(yytext);
> if (keyword != NULL)
> return keyword->value;
>
> /* Is it a C keyword? */
> keyword = ScanCKeywordLookup(yytext);
> if (keyword != NULL)
> return keyword->value;
>
> /*
> * None of the above. Return it as an identifier.
> *
> * The backend will attempt to truncate
> and case-fold
> * the identifier, but I see no good reason for ecpg
> * to do so; that's just another way that
> ecpg could get
> * out of step with the backend.
> */
> base_yylval.str = mm_strdup(yytext);
> return IDENT;
>
> Shouldn't we perform both SQL and C table lookup in C state as well?
>
I spent some more time thinking over this and found that, we would
actually never come to a situation where in C state we need to have a
SQL keyword lookup and hence, SQL keywords lookup might not be
required in C state.
> Let's consider the following test where a double datatype is used
> inside the declare section.
>
> EXEC SQL BEGIN DECLARE SECTION;
> double d1;
> EXEC SQL END DECLARE SECTION;
>
> In above case "double" would be scanned in C state by <C>{identifiers}
> rule which would search for double keyword in ScanCKeywords[] table
> and since it doesn't find it, it returns some IDENT keyword for it.
>
> However, if above is written as "EXEC SQL double d;" then, double
> would be scanned in SQL state by <SQL>{identifiers} rule which would
> first search for double in SQLScanKeywords[] followed by
> ScanCKeywords[]. In this case, as double is declared in
> SQLScanKeywords[], it would return some valid keyword for double.
>
> --
> With Regards,
> Ashutosh Sharma
> EnterpriseDB:http://www.enterprisedb.com