Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fhuqS-0001Qa-2E for pgsql-interfaces@arkaria.postgresql.org; Tue, 24 Jul 2018 10:47:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1fhuqQ-00082b-8D for pgsql-interfaces@arkaria.postgresql.org; Tue, 24 Jul 2018 10:47:06 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fhuqQ-00082U-0R for pgsql-interfaces@lists.postgresql.org; Tue, 24 Jul 2018 10:47:06 +0000 Received: from mail-it0-x231.google.com ([2607:f8b0:4001:c0b::231]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1fhuqK-0000A3-Aj for pgsql-interfaces@lists.postgresql.org; Tue, 24 Jul 2018 10:47:02 +0000 Received: by mail-it0-x231.google.com with SMTP id w16-v6so3108204ita.0 for ; Tue, 24 Jul 2018 03:46:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=g2Gc1f7IfBubpE50Y3FF63hjnHY8tJeyqDYBHcxIn2A=; b=IUX+vmbfLzjzDbcleZKrvet62BKcGZNF/b1zGt6UHJqte3SAG7fCUetmhe4efnOe84 6wkm8GvOlyOIyCyQkApVN+f6Hbr6CHKotdBAvKnadWKetX6totgDDQO6p9JDgn+EPRJY s8gClmXCmLk4pPW25EdMvzprwyIq3x79NGQ6C/h/fhi1bHq8SjzuhuiXtmUB6r+xJs58 nlju9hWBePfmNFtet+cSkW3z9u3dddUGvtF1Et1vWMp1X0mNu+mBpZhNow03N+GKjYI+ KEO+SW+SFkUcibOP/L3+SJOkwoMRzxfBBab3eY3oU1Ei+xm8r1XmF+/Oy78DhTqHIBg4 ZFig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=g2Gc1f7IfBubpE50Y3FF63hjnHY8tJeyqDYBHcxIn2A=; b=N0Dc269lIkktx/zgITjMrJAbFvMCDoX/6l7aNkSaUi5YEFA4iQfpTrk7J4CHHsIbBP h0I5fzM6qNGEFDH3OaxKw87EPgMPCj9v6vTgn0bMpOhBaqZGxrh52oa5R4xjwMrmgbhL 987S5siC7d/sKefTo1ZGMC5mR9kWRisitx/NR18sev9OXiWELw0/sasirK9175BtyD2E lvyNyWHiBZ9XuXG8w9SlIOSoNG14Ph6qM/gCSvhgLuQlmT4lCQkA3Of1WTCdoNWpbWm0 3ESP4J+3Yom7oplgCm5nsFpjIMGqeQi7QeBgFUsSoclrKwlOjznzXMQd2U8DJVA85BzD Eugw== X-Gm-Message-State: AOUpUlEDFd8gnWkhQsyIB47m7aOhsRoGrwN4003ya4p1ESQif71HF4L7 Vb8MIrs30SKtWIOVxeXab5l2df644FJYNmQ/4fwS/C6X X-Google-Smtp-Source: AAOMgpdyhv257eRMqPHdQiVQcnN03sCxplRjBPOJSVc3SiXLbbwwSShkf57LS2pLMXt1Zp6gbuXqD7TEJZ00kMEBfmo= X-Received: by 2002:a24:b302:: with SMTP id e2-v6mr2242492itf.132.1532429217922; Tue, 24 Jul 2018 03:46:57 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a02:5989:0:0:0:0:0 with HTTP; Tue, 24 Jul 2018 03:46:57 -0700 (PDT) From: Ashutosh Sharma Date: Tue, 24 Jul 2018 16:16:57 +0530 Message-ID: Subject: Host variables in ecpg To: pgsql-interfaces@lists.postgresql.org Cc: Michael Meskes Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk 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 '{identifier}' rule whereas incase of 2 (i.e. when using implicit declare section) the host variables gets scanned in SQL state using '{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 {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; } } {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 {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 {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