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 |
On Tue, Jul 24, 2018 at 4:16 PM, Ashutosh Sharma <[hidden email]> 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 |
Free forum by Nabble | Edit this page |