blob: b3ab7d2857c7fa28c789adf77556a204a4050b2f [file] [log] [blame]
/********************************************************************
//
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: sqlci_yacc.y
* Description: Parser for mxci commands.
*
*
* Created: 7/10/95
* Modified: $ $Date: 2006/11/01 01:44:52 $ (GMT)
* Language: C++
*
*
*
*
*****************************************************************************
*/
%{
#include "Platform.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "ComAnsiNamePart.h"
#include "ParserMsg.h" // StoreSyntaxError(...ComDiagsArea&...)
#include "Sqlci.h"
#include "str.h"
#include "nawstring.h"
#define SQLCIPARSEGLOBALS__INITIALIZE
#include "SqlciParseGlobals.h"
#include "HeapLog.h"
#include "charinfo.h"
#include "conversionHex.h"
#include "ComDistribution.h"
#include "ComObjectName.h"
#include "ComSchemaName.h"
extern char **environ;
#define ENVIRON environ
#define PUTENV putenv
extern NAHeap sqlci_Heap;
extern "C" {int yylex (void); }
extern ComDiagsArea sqlci_DA;
extern char *sqlcitext;
static char *identifier_name_internal;
static char *identifier_name_internal2;
static int pos_internal;
static int pos_internal2;
static int pos_internal3;
static char *get_stats_str;
//extern "C" { void yyerror(const char *sb); };
static void sqlcierror(const char *) // (const char *errtext)
{
// Re-initialize the following variables which are used in sqlci_lex.l
SqlciParse_SyntaxErrorCleanup = 0;
SqlciParse_IdentifierExpected = 0;
if (!SqlciParse_HelpCmd)
{
// So syntax errmsg caret points properly, when input is an extra
// dangling #else or #endif --
// emit ^ not ^
if (SqlciParse_InputPos <= 2)
if (*SqlciParse_InputStr == '#')
SqlciParse_InputPos = 0;
SqlciError (SQLCI_SYNTAX_ERROR, (ErrorParam *) 0);
StoreSyntaxError(SqlciParse_InputStr, SqlciParse_InputPos, sqlci_DA, 0);
}
} // sqlcierror
enum EQuotedStringWithoutPrefixFlag { eNOT_QUOTED_STRING_WITHOUT_CHARSET_PREFIX = 0,
eQUOTED_STRING_WITHOUT_CHARSET_PREFIX = 1 };
static short trimValueText(int/*offset*/ &i,
int/*length*/ &len,
int/*bool*/ &quoted,
CharInfo::CharSet /*charset code*/ &cs,
int/* bool*/ &inhexdecimal,
int /*bool*/ quoting_allowed = -1,
int/*bool*/ use_i_as_is = 0,
int/*bool*/ cs_allowed = 0,
EQuotedStringWithoutPrefixFlag * pQuotedStrWithoutPrefixFlag = NULL
, int/*bool*/ keepValueTextAsIs = 0/*false*/
)
{
// Process the value text:
// remove the trailing semicolon and any squotes (')
// but leave in any dquotes (").
//
// Returns TRUE if syntax error (error in quoted string, basically --
// which should be already caught by class InputStmt; see its logic
// around SQLCI_INPUT_MISSING_QUOTE).
if (pQuotedStrWithoutPrefixFlag != NULL)
*pQuotedStrWithoutPrefixFlag = eNOT_QUOTED_STRING_WITHOUT_CHARSET_PREFIX;
quoted = 0;
cs = CharInfo::UnknownCharSet;
inhexdecimal = 0;
if (!use_i_as_is)
{
i = SqlciParse_InputPos - 1;
// Now the i'th character is a separator char that Lex found,
// separating the Define name from its value.
// The following test allows
// SET ENVVAR nam;
// SET ENVVAR nam ;
// SET ENVVAR nam val;
// SET ENVVAR nam 'val';
// SET ENVVAR nam "val";
// SET ENVVAR nam'val'; -- on the analogy of Ansi syntax which
// SET ENVVAR nam"val"; -- allows SELECT * FROM tbl"corrName";
// SET ENVVAR nam :val; -- value is :val
// SET ENVVAR nam =val; -- value is =val
// but not
// SET ENVVAR nam:val;
// SET ENVVAR nam=val;
//
if (SqlciParse_OriginalStr[i] != ';' &&
SqlciParse_OriginalStr[i] != '\'' &&
SqlciParse_OriginalStr[i] != '\"' &&
!isspace(SqlciParse_OriginalStr[i]) &&
!isspace(SqlciParse_OriginalStr[i-1]))
return -1; // error: space separator needed
}
// skip leading blanks
while (isspace(SqlciParse_OriginalStr[i])) i++;
// remember the start position of '_' in case we need to go back to position i
int i_orig = i;
NAString origValueText(&SqlciParse_OriginalStr[i_orig]); // for the keepValueTextAsIs case
// determine if the value is has a valid character set prefix
if ( cs_allowed && SqlciParse_OriginalStr[i] == '_' )
{
int k = i+1;
char c;
while ((c=SqlciParse_OriginalStr[k])) {
if ( c == '\''|| c == ' ' ) // quoted or hexadecimal value
{
SqlciParse_OriginalStr[k] = '\0'; // temp. null terminate the prefix
NAString csPrefix(&SqlciParse_OriginalStr[i+1]);
SqlciParse_OriginalStr[k] = c; // restore
csPrefix.toUpper();
cs = CharInfo::getCharSetEnum(csPrefix); // check the prefix
if ( CharInfo::isCharSetFullySupported(cs) ) {
i = k; // mark the start of the string after the prefix
}
break;
}
k++;
}
// A string in hexadecimal format begins with ' x' or ' X'.
if ( SqlciParse_OriginalStr[i] == ' ' &&
SqlciParse_OriginalStr[i+1] &&
toupper(SqlciParse_OriginalStr[i+1]) == 'X' ) {
inhexdecimal = 1; // mark the hexadecimal format.
i += 2; // skip ' x'. Suppose to point at '.
}
} else {
// no cs name prefix. Check if it is a hexadecimal string.
if ( toupper(SqlciParse_OriginalStr[i]) == 'X' &&
SqlciParse_OriginalStr[i+1] == '\''
) {
inhexdecimal = 1; // mark the hexadecimal format.
i += 1; // skip 'x'. Suppose to point at '.
}
}
char delimQuote = '\'';
if (SqlciParse_OriginalStr[i] == '\'' || // quoted value
SqlciParse_OriginalStr[i] == '"')
{
delimQuote = SqlciParse_OriginalStr[i];
quoted = -1;
// Remove the leading single quote as procedure comments indicate.
NAString temptrail(&SqlciParse_OriginalStr[i+1]);
strcpy(&SqlciParse_OriginalStr[i], temptrail);
} else
i = i_orig; // need to abadone the charset name assumption.
SqlciParse_InputPos = i; // for sqlcierror message
if (quoted && !quoting_allowed) return -1; // error
int j = strlen(SqlciParse_OriginalStr) - 1;
// skip any blanks between end of SqlciParse_OriginalStr and the semicolon.
while (isspace(SqlciParse_OriginalStr[j])) j--;
j--; // skip semicolon
while (j >= i && // skip trailing blanks
isspace(SqlciParse_OriginalStr[j])) j--;
if (j < i && quoted) return -1; // error: unmatched begin quote
if (SqlciParse_OriginalStr[j] == delimQuote)
{
if (!quoted) return -1; // error: unmatched end quote
quoted = +1;
j--;
}
if (quoted < 0) return -1; // error: unmatched begin quote
if (j >= i)
if (quoted)
{
// if nonempty string within quotes, convert any embedded pair of quotes
// (i.e. a quoted quote) into one quote, by left shifting
//
// **this modifies SqlciParse_OriginalStr (which points to the same
// **buffer as SqlciParse_InputStr)!
//#ifdef NA_WINNT
SqlciParse_OriginalStr[j+1] = '\0'; // mark end of value text
//#else
// Remove the trailing single quote, but save the semi-colon on the TANDEM
// platform.
// SqlciParse_OriginalStr[j+1] = '\;'; // replace quote with a semi-colon
// SqlciParse_OriginalStr[j+2] = '\0'; // mark end of string
//#endif // NA_WINNT
for (j = i; SqlciParse_OriginalStr[j]; j++)
if (SqlciParse_OriginalStr[j] == delimQuote)
{
if (SqlciParse_OriginalStr[j+1] != delimQuote)
return -1; // error: unmatched embedded q
NAString temptrail(&SqlciParse_OriginalStr[j+1]);
strcpy(&SqlciParse_OriginalStr[j], temptrail);
}
j--;
}
else if (quoting_allowed)
{
// if nonempty nonquoted string -- but quoting allowed --
// then any embedded quotes or blanks are an error
for (int k = i; k <= j; k++)
if (SqlciParse_OriginalStr[k] == delimQuote ||
isspace(SqlciParse_OriginalStr[k]))
{
SqlciParse_InputPos = j; // for sqlcierror message
return -1; // error
}
}
//else embedded quotes allowed and passed thru unchanged
if (keepValueTextAsIs)
{
TrimNAStringSpace(origValueText, 0/*false*/ /*leading?*/, 1/*true*/ /*trailing?*/);
if (origValueText.data()[origValueText.length()-1] == ';')
origValueText.remove(origValueText.length()-1);
TrimNAStringSpace(origValueText, 0/*false*/ /*leading?*/, 1/*true*/ /*trailing?*/);
strcpy(&SqlciParse_OriginalStr[i_orig], origValueText.data());
len = origValueText.length();
}
else
len = j - i + 1;
if (len < 0) len = 0;
if ( quoted ) {
if ( cs == CharInfo::UnknownCharSet ) {
if (pQuotedStrWithoutPrefixFlag != NULL)
*pQuotedStrWithoutPrefixFlag = eQUOTED_STRING_WITHOUT_CHARSET_PREFIX;
cs = SqlciEnvGlobal->getTerminalCharset();
}
} else
inhexdecimal = 0; // reset the hex indicator if the value is not quoted.
// Consumed entire input (need this for pre-YYACCEPT test in sqlci_cmd).
// Of course, a subsequent call to this routine on the same string will
// have to use the use_i_as_is parameter and pass in a valid i ...
//
SqlciParse_InputPos = strlen(SqlciParse_OriginalStr) + 1;
return 0; // no error
} // trimValueText
static char * FCString (const char *idString, int isFC)
{
char * cmd_str = new char[strlen(SqlciParse_OriginalStr)];
cmd_str[0]='\0';
// Skip leading blanks
int i = 0;
while (isspace(SqlciParse_OriginalStr[i]))
i++;
const char *s;
if (isFC)
// i+2 - to skip the two characters of 'fc'
s = strstr(&SqlciParse_OriginalStr[i+2], idString);
else
s = strstr(&SqlciParse_OriginalStr[i], idString);
if (s)
{
for ( ; *s; s++)
{
if (*s != ';')
{
strncat (cmd_str, s, 1);
}
}
}
return cmd_str;
}
#define REPOSITION_SqlciParse_InputPos \
{ SqlciParse_InputPos = strlen(SqlciParse_InputStr); }
%}
%token NOSQL
%token CONTAINSQL
%token READSQL
%token MODIFYSQL
%token RESETVIOLATION
%token CHECKVIOLATION
%token NoAutoXact
%token DESCRIBEToken
%token CREATECONTEXT
%token CURRENTCONTEXT
%token SWITCHCONTEXT
%token DELETECONTEXT
%token RESETCONTEXT
%token ADDtoken
%token ALLtoken
%token BACKSLASH
%token BRIEF
%token DETAIL
%token CANCEL
%token CLASStoken
%token CLEANUP
%token CLEAR
%token COMMA
%token COMMANDStoken
%token CONTROL
%token OSIM
%token COPY
%token CPU_VALUE
%token ERRORtoken
%token DEFAULTtoken
%token DEFAULT_CHARSETtoken
%token DISPLAY
%token DISPLAY_STATISTICS
%token DISPLAY_QUERYID
%token DISPLAY_EXPLAIN
%token DISPLAY_QC
%token DISPLAY_QC_ENTRIES
%token DISPLAY_QC_ENTRIES_NOTIME
%token DISPLAY_USE_OF
%token EDIT
%token MXCI_TOK_ENV
%token EXIT
%token EXPLAIN
%token FIRST
%token FC
%token FILEtoken
%token FILEINFO
%token FILENAMES
%token FILES
%token GENERATEtoken
%token MERGEtoken
%token METADATAtoken
%token REPLICATEtoken
%token GETtoken
%token GETSTATISTICStoken
%token HISTORY
%token HYPHEN
%token INFER_CHARSET
%token INFOtoken
%token INtoken
%token INFILE
%token SHOWSTATS
%token SHOWTRANSACTION
%token INVOKE
%token LISTCOUNT
%token LISTMODULES
%token LOADtoken
%token EXTRACTtoken
%token LOCK
%token LOCKINGtoken
%token LPAREN
%token MAPtoken
%token MIGRATE
%token MODE
%token MODIFY
%token MODIFYV
%token MSCKtoken
%token NEXT
%token NOEtoken
%token OBEY
%token OBJECTtoken
%token OFtoken
%token OFF
%token ON
%token OPTIONStoken
%token ISO_MAPPING
%token OUTFILE
%token PARAM
%token PARSERFLAGS
%token SQ_LINUX_PATTERN
%token PATTERN_AS_IS
%token PID_VALUE
%token PROCEDUREtoken
%token PURGEDATA
%token POPULATE
%token VALIDATEtoken
%token QUIESCE
%token REFRESH
%token REPEAT
%token REPORT
%token RESET
%token RESULT
%token RPAREN
%token SETtoken
%token SETENV
%token SHOW
%token SHOWCONTROL
%token SHOWDDL
%token SHOWPLAN
%token SHOWSHAPE
%token SHOWSET
%token SQL
%token SQLINFO
%token SQLNAMES
%token STATEMENTtoken
%token STOREtoken
%token SYNTAX
%token SYSTEMtoken
%token EXAMPLE
%token STATISTICS
%token SET_TABLEtoken
%token SET_TRANSACTIONtoken
%token TERMINAL_CHARSET
%token TRANSFORM
%token TRUNCATE
%token WITH
%token UNLOCK
%token UPD_STATS
%token UPD_HIST_STATS
%token USERtoken
%token USING
%token TABLE
%token VALUES
%token VALIDATE
%token VERBOSE
%token VERIFY
%token VERSIONtoken
%token WAITtoken
%token DEFINEtoken ENVVARtoken PREPARED SESSIONtoken
%token LOG LS CD SH SHELL
%token SELECTtoken UPDATEtoken INSERTtoken DELETEtoken UPSERTtoken
%token ROWSETtoken REPOSITORYtoken
%token CREATE ALTER DROP PREPAREtoken EXECUTEtoken FROM
%token DECLAREtoken OPENtoken CLOSEtoken FETCHtoken DEALLOCtoken
%token CURSORtoken FORtoken CPU PID QID ACTIVEtoken ACCUMULATEDtoken
%token PERTABLEtoken PROGRESStoken
%token TOK_BEGIN COMMIT ROLLBACK WORK
%token SQLCI_CMD SQL_STMT UTIL_STMT EXIT_STMT ERROR_STMT SHELL_CMD
%token IDENTIFIER NUMBER PARAM_NAME PATTERN_NAME FILENAME
%token QUOTED_STRING
%token DQUOTED_STRING
%token GRANTtoken REVOKEtoken
%token REGISTER UNREGISTER
%token GIVE
%token INITIALIZE REINITIALIZE
%token CATALOG SCHEMA
%token HIVEtoken
%token PROCESStoken
%token IF WHILE
%token MPLOC
%token NAMETYPE
%token SIGNAL
%token UIDtoken
%token CURSORWITH
%token WITHOUT
%token HOLD
%token INTERNAL
%token MVLOG
%token UNLOAD
%token CALLToken
%token COMMENTtoken
%union {
enum ComRoutineSQLAccess sql_access_mode_type;
SqlCliCmd * sqlcli_cmd_type;
SqlciCmd * sqlci_cmd_type;
SqlciNode * sql_cmd_type;
ShellCmd * shell_cmd_type;
int intval_type;
char * stringval_type;
dml_type dml_stmt_type;
Reset::reset_type reset_stmt_type_;
Show::show_type show_stmt_type_;
SqlciCursorInfo *cursor_info_type_;
}
%type <sql_access_mode_type> sql_access_mode;
%type <sqlcli_cmd_type> sqlcli_cmd
%type <sqlci_cmd_type> sqlci_cmd
%type <sql_cmd_type> sql_cmd
%type <shell_cmd_type> shell_cmd
%type <stringval_type> IDENTIFIER
%type <stringval_type> PARAM_NAME
%type <stringval_type> PATTERN_NAME
%type <stringval_type> PID_VALUE
%type <stringval_type> CPU_VALUE
%type <stringval_type> QUOTED_STRING
%type <stringval_type> DQUOTED_STRING
%type <stringval_type> NUMBER
%type <stringval_type> FILENAME
%type <dml_stmt_type> dml_type
%type <dml_stmt_type> dml_simple_table_type
%type <reset_stmt_type_> reset_type_;
%type <show_stmt_type_> show_type_;
%type <stringval_type> section_name_;
%type <stringval_type> HYPHEN;
%type <intval_type> commands_only;
%type <intval_type> stats_active_clause;
%type <intval_type> stats_merge_clause;
%type <stringval_type> explain_options;
%type <cursor_info_type_> cursor_info;
%type <intval_type> optional_rs_index;
%type <stringval_type> qid_identifier;
%start statement
%%
statement : sqlcli_cmd
{
SqlciParseTree = (SqlciNode *) $1;
YYACCEPT;
}
| sqlci_cmd
{
// Accept if we're at/past the end of the cmd
// or if only blanks and semicolons remain;
// otherwise, syntax error.
//
unsigned pos = SqlciParse_InputPos-1;
if (pos < strlen(SqlciParse_InputStr))
{
const char *s = &SqlciParse_InputStr[pos];
for ( ; *s; s++)
if (!isspace(*s) && *s != ';')
{sqlcierror("");YYERROR;}
}
SqlciParseTree = (SqlciNode *) $1;
YYACCEPT;
}
| sql_cmd
{
SqlciParseTree = (SqlciNode *) $1;
YYACCEPT;
}
| shell_cmd
{
SqlciParseTree = (SqlciNode *) $1;
YYACCEPT;
}
;
sqlcli_cmd : CHECKVIOLATION
{
$$ = new CheckViolation();
}
| RESETVIOLATION sql_access_mode
{
$$ = new ResetViolation($2);
}
| CREATECONTEXT
{
$$ = new CreateContext();
}
| CREATECONTEXT NoAutoXact
{
$$ = new CreateContext(TRUE/* noAutoXact */);
}
| CURRENTCONTEXT
{
$$ = new CurrentContext();
}
| SWITCHCONTEXT NUMBER
{
$$ = new SwitchContext(atoi($2));
}
| DELETECONTEXT NUMBER
{
$$ = new DeleteContext(atoi($2));
}
| RESETCONTEXT NUMBER
{
$$ = new ResetContext(atoi($2));
}
;
sql_access_mode : NOSQL
{
$$ = COM_NO_SQL;
}
| CONTAINSQL
{
$$ = COM_CONTAINS_SQL;
}
| READSQL
{
$$ = COM_READS_SQL;
}
| MODIFYSQL
{
$$ = COM_MODIFIES_SQL;
}
;
sqlci_cmd : MODE SQL
{
$$ = new Mode (Mode::SQL_ , TRUE);
}
| OBEY FILENAME section_name_
{
$$ = new Obey($2, strlen($2), $3);
}
| MXCI_TOK_ENV
{
$$ = new Env(0,0);
}
| USERtoken IDENTIFIER
{
char userName[strlen($2)+1];
for (size_t i=0; i < strlen($2); i++)
{
userName[i] = toupper($2[i]);
}
userName[strlen($2)] = 0;
$$ = new ChangeUser(userName, strlen(userName));
}
| REPEAT
{
// "!" command, a la SQL/MP aRepeat (0,0);
$$ = new FCRepeat (0,(short)0);
}
| REPEAT REPEAT
{
// "!!" command, a la Unix csh
$$ = new FCRepeat (0,(short)0);
}
| REPEAT NUMBER
{
$$ = new FCRepeat (atoi($2), 0);
}
| REPEAT HYPHEN NUMBER
{
$$ = new FCRepeat (atoi($3), -1);
}
| REPEAT IDENTIFIER
{
char *fcString = FCString ($2, 0);
$$ = new FCRepeat(fcString, (long)strlen(fcString));
REPOSITION_SqlciParse_InputPos;
}
| REPEAT LPAREN NUMBER RPAREN
{
$$ = new FCRepeat (atoi($3), 0);
}
| FC
{
$$ = new FixCommand(0, (short)0);
}
| FC NUMBER
{
$$ = new FixCommand(atoi($2), 0);
}
| FC HYPHEN NUMBER
{
$$ = new FixCommand(atoi($3), -1);
}
| FC IDENTIFIER
{
char *fcString = FCString ($2, 1);
$$ = new FixCommand(fcString, (long)strlen(fcString));
REPOSITION_SqlciParse_InputPos;
}
| FC LPAREN NUMBER RPAREN
{
$$ = new FixCommand(atoi($3), 0);
}
| LOG IDENTIFIER commands_only
{
identifier_name_internal = new char[strlen($2)+1];
strcpy(identifier_name_internal, $2);
}
CLEAR
{
$$ = new Log(identifier_name_internal, strlen(identifier_name_internal), Log::CLEAR_, $3);
}
| LOG IDENTIFIER commands_only
{
$$ = new Log($2, strlen($2), Log::APPEND_, $3);
}
| LOG FILENAME commands_only
{
identifier_name_internal = new char[strlen($2)+1];
strcpy(identifier_name_internal, $2);
}
CLEAR
{
$$ = new Log(identifier_name_internal, strlen(identifier_name_internal), Log::CLEAR_, $3);
}
| LOG FILENAME commands_only
{
$$ = new Log($2, strlen($2), Log::APPEND_, $3);
}
| LOG
{
$$ = new Log(0,0, Log::STOP_, 0);
}
| HISTORY
{
$$ = new History(0,0);
}
| HISTORY NUMBER
{
$$ = new History($2,strlen($2));
}
| EXIT
{
$$ = new Exit(0,0);
}
| ERRORtoken NUMBER
{
$$ = new Error($2, strlen($2), Error::DETAIL_);
}
| ERRORtoken NUMBER COMMA BRIEF
{ $$ = new Error($2, strlen($2), Error::BRIEF_);
}
| ERRORtoken NUMBER COMMA DETAIL
{ $$ = new Error($2, strlen($2), Error::DETAIL_);
}
| SETtoken PARAM PARAM_NAME
{
int i, len, quoted;
CharInfo::CharSet cs;
int inhexadecimal;
EQuotedStringWithoutPrefixFlag quotedStrWithoutPrefixFlag;
if (trimValueText(i, len, quoted, cs, inhexadecimal, -1, 0, -1,
&quotedStrWithoutPrefixFlag)) {sqlcierror("");YYERROR;}
//if (len <= 0 && !quoted) {sqlcierror("");YYERROR;}
// see if input was of form "set param ?p null;".
// If yes, this param is a null value.
short null_param_val = 0;
if (len == 4 && !quoted)
{
char buf[4];
for (int k = 0; k < 4; k++)
buf[k] = toupper(SqlciParse_OriginalStr[i+k]);
null_param_val = (strncmp(buf, "NULL", 4) == 0);
}
if (null_param_val)
$$ = new SetParam($3, strlen($3), (char*)0, -1);
else {
char* pvalue = &SqlciParse_OriginalStr[i];
if ( inhexadecimal ) {
NAWString pvalue_in_wchar(CharInfo::ISO88591, pvalue);
void* result = NULL;
enum hex_conversion_code code =
verifyAndConvertHex(pvalue_in_wchar, pvalue_in_wchar.length(),
L'\'', cs, &sqlci_Heap, result);
switch ( code ) {
case SINGLE_BYTE:
{
NAString* conv_pvalue = (NAString*)result;
$$ = new SetParam($3, strlen($3),
(char*)(conv_pvalue->data()), conv_pvalue->length(), cs);
if (quotedStrWithoutPrefixFlag == eQUOTED_STRING_WITHOUT_CHARSET_PREFIX)
{
NAWString wstr(SqlciEnvGlobal->getTerminalCharset(),
conv_pvalue->data(), conv_pvalue->length());
SetParam * pSetParam = (SetParam *)$$;
pSetParam->setUTF16ParamStrLit(wstr.data(), wstr.length());
pSetParam->setQuotedStrWithoutPrefixFlag(TRUE);
pSetParam->setTermCharSet(SqlciEnvGlobal->getTerminalCharset());
}
// NADELETE() is not a const func while this routine is. Mask out the warning
NADELETE(conv_pvalue, NAString, &sqlci_Heap);
}
break;
case DOUBLE_BYTE:
{
NAWString* conv_pvalue = (NAWString*)result;
$$ = new SetParam($3, strlen($3),
(NAWchar*)(conv_pvalue->data()), conv_pvalue->length(), cs);
// NADELETE() is not a const func while this routine is. Mask out the warning
NADELETE(conv_pvalue, NAWString, &sqlci_Heap);
}
break;
default:
sqlcierror("");YYERROR;
}
} else {
switch (cs) {
case CharInfo::UNICODE:
{
NAWString wstr(SqlciEnvGlobal->getTerminalCharset(), pvalue, len);
$$ = new SetParam($3, strlen($3), (NAWchar*)wstr.data(), wstr.length(), cs);
}
break;
case CharInfo::KANJI_MP:
case CharInfo::KSC5601_MP:
if ( len % 2 != 0 )
{
// restore the closing two single quotes and ';' removed
// inside the trimValueText() call. The string starts
// at pvalue. We guarantee to have enough space here
// because trimValueText() will bail out if no single
// quotes present.
// We need to restore the closing single quotes and ';'
// so that in the second attempt of sqlci cmd parsing,
// the error can be caught again. Otherwise, _kanji'a'
// becomes _kanjia after first parsing attempt. That
// string is legal and is different than the one actually
// typed.
// It is difficult to remove the KLRUGE of 2nd parsing
// attempt in sqlciparser.cpp, func sqlci_parser().
// A lot of regressions will fail if we do so.
int k = strlen(pvalue);
for ( int x=k; x>=1; x-- ) {
pvalue[x] = pvalue[x-1];
}
*pvalue = '\'';
*(pvalue+k+1) = '\'';
*(pvalue+k+2) = ';';
*(pvalue+k+3) = '\0';
sqlcierror("");YYERROR;
}
$$ = new SetParam($3, strlen($3), (NAWchar*)pvalue, len/2, cs);
break;
// case CharInfo::ISO88591:
// case CharInfo::UTF8:
// case CharInfo::SJIS:
// case CharInfo::GB2312:
// case CharInfo::GBK:
// case CharInfo::...:
default:
{
SetParam * pSetParam = NULL;
if (quotedStrWithoutPrefixFlag == eQUOTED_STRING_WITHOUT_CHARSET_PREFIX)
{
// SqlciEnvGlobal->getInferCharset() == TRUE || FALSE
pSetParam = new SetParam($3, strlen($3), pvalue, len, cs);
NAWString wstr(cs, pvalue, len);
pSetParam->setUTF16ParamStrLit(wstr.data(), wstr.length());
pSetParam->setQuotedStrWithoutPrefixFlag(TRUE);
pSetParam->setTermCharSet(SqlciEnvGlobal->getTerminalCharset());
}
else
pSetParam = new SetParam($3, strlen($3), pvalue, len, cs);
$$ = pSetParam;
}
break;
}
}
}
}
| SETtoken SQ_LINUX_PATTERN PATTERN_NAME
{
int i, len, quoted;
CharInfo::CharSet cs;
int inhexadecimal;
if (trimValueText(i, len, quoted, cs, inhexadecimal)) {sqlcierror("");YYERROR;}
$$ = new SetPattern($3, strlen($3),
&SqlciParse_OriginalStr[i], len);
}
| SETtoken PATTERN_AS_IS PATTERN_NAME
{
int i, len, quoted;
CharInfo::CharSet cs;
int inhexadecimal;
EQuotedStringWithoutPrefixFlag quotedStrWithoutPrefixFlag;
if ( trimValueText( i, len, quoted, cs, inhexadecimal
, -1/*true*/ // quoting_allowed?
, 0/*false*/ // use_i(1st_param)_as_is?
, -1/*true*/ // cs_allowed?
, &quotedStrWithoutPrefixFlag
, -1/*true*/ // keepValueTextAsIs
) )
{sqlcierror("");YYERROR;}
$$ = new SetPattern($3, strlen($3),
&SqlciParse_OriginalStr[i], len);
}
| SETtoken SHOWSHAPE ON
{
$$ = new Shape(TRUE, NULL, NULL);
}
| SETtoken SHOWSHAPE OFF
{
$$ = new Shape(FALSE, NULL, NULL);
}
| SETtoken SHOWSHAPE INFILE FILENAME
{
identifier_name_internal = new char[strlen($4)+1];
strcpy(identifier_name_internal, $4);
}
OUTFILE FILENAME
{
$$ = new Shape(FALSE, identifier_name_internal, $7);
}
| SETtoken STATISTICS OFF
{
$$ = new Statistics(0,0,Statistics::SET_OFF, NULL);
}
| SETtoken STATISTICS ON
{
// display statistics in old format
$$ = new Statistics(NULL, 0, Statistics::SET_ON,
(char *)"of");
}
| SETtoken STATISTICS PERTABLEtoken
{
$$ = new Statistics(NULL, 0, Statistics::SET_ON,
(char *)"PERTABLE");
}
| SETtoken STATISTICS PROGRESStoken
{
$$ = new Statistics(NULL, 0, Statistics::SET_ON,
(char *)"PROGRESS");
}
| SETtoken STATISTICS DEFAULTtoken
{
$$ = new Statistics(NULL, 0, Statistics::SET_ON,
(char *)"DEFAULT");
}
| SETtoken STATISTICS ALLtoken
{
$$ = new Statistics(NULL, 0, Statistics::SET_ON,
(char *)"ALL");
}
| SETtoken STATISTICS ON COMMA GETtoken STATISTICS
{
// display stats in new format
$$ = new Statistics(NULL, 0, Statistics::SET_ON, NULL);
}
| SETtoken STATISTICS ON COMMA GETtoken STATISTICS COMMA OPTIONStoken QUOTED_STRING
{
// display stats in new format based on options in
// quoted_string
$$ = new Statistics(NULL, 0, Statistics::SET_ON,
$9);
}
| SETtoken LISTCOUNT NUMBER
{
$$ = new ListCount($3, strlen($3));
}
| SETtoken LISTCOUNT
{
if ((sqlcitext) && (sqlcitext[0] != ';'))
{sqlcierror("");YYERROR;}
$$ = new ListCount(0, 0);
}
| SETtoken VERBOSE ON
{
$$ = new Verbose(0, 0, Verbose::SET_ON);
}
| SETtoken VERBOSE OFF
{
$$ = new Verbose(0, 0, Verbose::SET_OFF);
}
| SETtoken TERMINAL_CHARSET IDENTIFIER
{
$$ = new SetTerminalCharset($3);
}
| SETtoken ISO_MAPPING IDENTIFIER
{
$$ = new SetIsoMapping($3);
}
| SETtoken DEFAULT_CHARSETtoken IDENTIFIER
{
$$ = new SetDefaultCharset($3);
}
| SETtoken INFER_CHARSET NUMBER
{
$$ = new SetInferCharset($3);
}
| SETtoken INFER_CHARSET IDENTIFIER
{
$$ = new SetInferCharset($3);
}
| SETtoken INFER_CHARSET ON
{
$$ = new SetInferCharset((char *)"TRUE");
}
| SETtoken INFER_CHARSET OFF
{
$$ = new SetInferCharset((char *)"FALSE");
}
| SETtoken QID IDENTIFIER
{
// save qid val.
identifier_name_internal = new char[strlen($3)+1];
str_cpy_convert(identifier_name_internal, $3, strlen($3), TRUE);
identifier_name_internal[strlen($3)] = 0;
}
FORtoken
{
pos_internal = SqlciParse_InputPos;
}
IDENTIFIER
{
// remove trailing ";"
char * id = &SqlciParse_OriginalStr[pos_internal];
Lng32 i = strlen(&SqlciParse_OriginalStr[pos_internal]) -1;
while ((i > 0) && (id[i] != ';'))
i--;
id[i] = 0;
char * id2 = new char[strlen(id)+1];
str_cpy_convert(id2, id, strlen(id), TRUE);
id2[strlen(id)] = 0;
$$ = new QueryId (id2, strlen(id2),
TRUE, identifier_name_internal);
}
| RESET PARAM PARAM_NAME
{
$$ = new Reset(Reset::PARAM_, $3, strlen($3));
}
| RESET SQ_LINUX_PATTERN PATTERN_NAME
{
$$ = new Reset(Reset::PATTERN_, $3, strlen($3));
}
| RESET reset_type_
{
if ((sqlcitext) && (sqlcitext[0] != ';'))
{sqlcierror("");YYERROR;}
$$ = new Reset($2);
}
| SHOW show_type_
{
$$ = new Show($2, TRUE);
}
| DISPLAY_QUERYID FORtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($3)+1];
str_cpy_convert(identifier_name_internal, $3, strlen($3), TRUE);
identifier_name_internal[strlen($3)] = 0;
$$ = new QueryId (identifier_name_internal,strlen(identifier_name_internal),
FALSE, NULL);
}
| DISPLAY_QUERYID
{
$$ = new QueryId (0,0, FALSE, NULL);
}
| SHOW PREPARED
{
if ((sqlcitext) && (sqlcitext[0] != ';'))
{sqlcierror("");YYERROR;}
$$ = new Show(Show::PREPARED_, TRUE);
}
| SHOW PREPARED ALLtoken
{
$$ = new Show(Show::PREPARED_, TRUE);
}
| WAITtoken
{
$$ = new Wait(NULL, 0);
}
;
commands_only :
COMMANDStoken { $$ = 1; }
| empty { $$ = 0; }
;
empty :
;
section_name_:
LPAREN IDENTIFIER RPAREN {$$ = $2;}
| {$$ = 0;}
;
reset_type_ :
PARAM {$$ = Reset::PARAM_;}
;
show_type_ :
CURSORtoken {$$ = Show::CURSOR_;}
| PARAM {$$ = Show::PARAM_;}
| SQ_LINUX_PATTERN {$$ = Show::PATTERN_;}
| SESSIONtoken {$$ = Show::SESSION_;}
| VERSIONtoken {$$ = Show::VERSION_;}
;
stats_active_clause :
ACTIVEtoken NUMBER { $$ = atoi($2); }
| ALLtoken { $$ = 0; }
| empty { $$ = 1; }
;
stats_merge_clause :
ACCUMULATEDtoken { $$ = SQLCLI_ACCUMULATED_STATS; }
| PERTABLEtoken { $$ = SQLCLI_PERTABLE_STATS; }
| PROGRESStoken { $$ = SQLCLI_PROGRESS_STATS; }
| DEFAULTtoken { $$ = SQLCLI_SAME_STATS; }
| empty { $$ = SQLCLI_DEFAULT_STATS; }
;
qid_identifier :
IDENTIFIER
{
// Convert IDENTIFIER to uppercase
identifier_name_internal2 = new char[strlen($1)+1];
str_cpy_convert(identifier_name_internal2, $1, strlen($1), TRUE);
identifier_name_internal2[strlen($1)] = '\0';
$$ = identifier_name_internal2;
}
| DQUOTED_STRING
{
// keep Double Quoted String as is
identifier_name_internal2 = new char[strlen($1)+1];
strcpy(identifier_name_internal2, $1);
$$ = identifier_name_internal2;
}
;
sql_cmd :
dml_type
{
$$ = new DML(SqlciParse_OriginalStr, $1, NULL);
REPOSITION_SqlciParse_InputPos;
}
| DECLAREtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
}
CURSORWITH HOLD FORtoken
{
pos_internal = SqlciParse_InputPos;
}
dml_simple_table_type
{
$$ =
new Cursor(identifier_name_internal,
Cursor::DECLARE, -1,
&SqlciParse_OriginalStr[pos_internal]);
REPOSITION_SqlciParse_InputPos;
((Cursor *)$$)->setHoldable(TRUE);
}
| DECLAREtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
(long) strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
}
CURSORtoken FORtoken
{
pos_internal = (int) SqlciParse_InputPos;
}
cursor_info
{
SqlciCursorInfo *cinfo = $7;
Cursor *c = new
Cursor(identifier_name_internal,
Cursor::DECLARE,
(short) cinfo->queryTextSpecified_,
cinfo->queryTextOrStmtName_);
c->setResultSetIndex(cinfo->resultSetIndex_);
$$ = c;
delete [] identifier_name_internal2;
identifier_name_internal2 = NULL;
delete cinfo;
REPOSITION_SqlciParse_InputPos;
}
| OPENtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
$$ =
new Cursor(identifier_name_internal,
Cursor::OPEN, 0, NULL);
}
| FETCHtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
$$ =
new Cursor(identifier_name_internal,
Cursor::FETCH, 0, NULL);
}
| CLOSEtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
$$ =
new Cursor(identifier_name_internal,
Cursor::CLOSE, 0, NULL);
}
| DEALLOCtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
$$ =
new Cursor(identifier_name_internal,
Cursor::DEALLOC, 0, NULL);
}
| PREPAREtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
}
FROM
{
pos_internal = SqlciParse_InputPos;
}
dml_type
{
$$ = new Prepare(identifier_name_internal,
&SqlciParse_OriginalStr[pos_internal], $6);
REPOSITION_SqlciParse_InputPos;
}
| DESCRIBEToken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
$$ = new DescribeStmt(identifier_name_internal, identifier_name_internal);
}
| EXECUTEtoken IDENTIFIER
{
// ## This kind of foolishness could be partly done
// ## away with, consolidated at least, if most of
// ## these "sql_cmd" productions were made
// ## "sqlci_cmd" ones (the pre-YYACCEPT logic for
// ## the latter would handle this generically).
if (sqlcitext[0] && sqlcitext[0] != ';')
{sqlcierror("");YYERROR;}
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
$$ = new Execute(identifier_name_internal,
identifier_name_internal, 0/*flag*/, SqlciEnvGlobal);
}
| EXECUTEtoken IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
}
USING
{
pos_internal = SqlciParse_InputPos;
if (SqlciParse_OriginalStr[pos_internal-1] == ',')
pos_internal--;
$$ = new Execute(identifier_name_internal,
&SqlciParse_OriginalStr[pos_internal], 1/*flag*/, SqlciEnvGlobal);
}
| DISPLAY_EXPLAIN explain_options IDENTIFIER
{
// returns "EXPLAIN [options 'x'] id;", sets deprecated warning
// The +16 allows space to add "options 'm' " when defaulted
long newStrLen = strlen(SqlciParse_OriginalStr) + 16;
char * newStr = new char[newStrLen+1];
if ($2)
{
strcpy(newStr, "EXPLAIN options '");
strcat(newStr, $2);
strcat(newStr, "' ");
}
else
{
strcpy(newStr, "EXPLAIN options 'm' ");
}
identifier_name_internal = new char[strlen($3)+1];
str_cpy_convert(identifier_name_internal, $3,
strlen($3), TRUE);
identifier_name_internal[strlen($3)] = 0;
strcat(newStr, identifier_name_internal);
strcat(newStr, ";");
sqlci_DA << DgSqlCode(15039);
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete identifier_name_internal;
delete newStr;
}
| DISPLAY_EXPLAIN explain_options PROCEDUREtoken
{
// Not a user-documented feature
// returns "EXPLAIN [options 'x'] procedure();", sets deprecated warning
// The +16 allows space to add "options 'm' " when defaulted
long newStrLen = strlen(SqlciParse_OriginalStr) + 16;
char * newStr = new char[newStrLen+1];
if ($2)
{
strcpy(newStr, "EXPLAIN ");
}
else
{
strcpy(newStr, "EXPLAIN options 'm' ");
}
strcat(newStr,
&SqlciParse_OriginalStr[strlen("DISPLAY_EXPLAIN")]);
sqlci_DA << DgSqlCode(15039);
$$ = new DML(newStr,
DML_DESCRIBE_TYPE, NULL);
REPOSITION_SqlciParse_InputPos;
delete newStr;
}
| DISPLAY_EXPLAIN explain_options dml_type
{
// returns "EXPLAIN [options 'x'] SQL-cmd;", sets deprecated warning
// The +16 allows space to add "options 'm' " when defaulted
long newStrLen = strlen(SqlciParse_OriginalStr) + 16;
char * newStr = new char[newStrLen+1];
if ($2)
{
strcpy(newStr, "EXPLAIN ");
}
else
{
strcpy(newStr, "EXPLAIN options 'm' ");
}
strcat(newStr,
&SqlciParse_OriginalStr[strlen("DISPLAY_EXPLAIN")]);
sqlci_DA << DgSqlCode(15039);
$$ = new DML(newStr,
DML_DESCRIBE_TYPE, NULL);
REPOSITION_SqlciParse_InputPos;
delete newStr;
}
| DISPLAY_STATISTICS
{
long newStrLen =
strlen("GET STATISTICS , options 'of';");
char * newStr = new char[newStrLen+1];
strcpy(newStr, "GET STATISTICS , options 'of';");
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete newStr;
}
| DISPLAY_STATISTICS IDENTIFIER
{
identifier_name_internal = new char[strlen($2)+1];
str_cpy_convert(identifier_name_internal, $2,
strlen($2), TRUE);
identifier_name_internal[strlen($2)] = 0;
long newStrLen =
strlen("GET STATISTICS FOR STATEMENT , options 'of';");
newStrLen += strlen(identifier_name_internal);
char * newStr = new char[newStrLen+1];
strcpy(newStr, "GET STATISTICS FOR STATEMENT ");
strcat(newStr, identifier_name_internal);
strcat(newStr, ", options 'of';");
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete newStr;
}
| DISPLAY_STATISTICS FORtoken CPU NUMBER
{
pos_internal = atoi($4);
}
stats_active_clause
{
pos_internal3 = $6;
}
stats_merge_clause
{
char * newStr = new char[200];
sprintf(newStr, "GET STATISTICS FOR CPU %d ACTIVE %d",
pos_internal, pos_internal3);
if ($8 == SQLCLIDEV_ACCUMULATED_STATS)
strcat(newStr, " ACCUMULATED");
strcat(newStr, " ;");
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete newStr;
}
| DISPLAY_STATISTICS FORtoken CPU CPU_VALUE
{
// This is of the form "FOR CPU \DOPEY.1"
identifier_name_internal2 = new char[strlen($4)+1];
str_cpy_convert (identifier_name_internal2, $4, strlen ($4), TRUE);
identifier_name_internal2[strlen($4)] = 0;
}
stats_active_clause
{
pos_internal3 = $6;
}
stats_merge_clause
{
long strLen = 100+strlen(identifier_name_internal2);
char *newStr = new char[strLen];
sprintf( newStr, "GET STATISTICS FOR CPU %s ACTIVE %d",
identifier_name_internal2, pos_internal3);
if ($8 == SQLCLIDEV_ACCUMULATED_STATS)
strcat(newStr, " ACCUMULATED");
strcat(newStr, " ;");
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete identifier_name_internal2;
delete newStr;
}
| DISPLAY_STATISTICS FORtoken PID NUMBER
{
pos_internal = atoi ($4);
}
COMMA NUMBER
{
pos_internal2 = atoi ($7);
}
stats_active_clause
{
pos_internal3 = $9;
}
stats_merge_clause
{
char *newStr = new char[200];
sprintf(newStr, "GET STATISTICS FOR PID %d,%d ACTIVE %d",
pos_internal, pos_internal2, pos_internal3);
if ($11 == SQLCLIDEV_ACCUMULATED_STATS)
strcat(newStr, " ACCUMULATED");
strcat(newStr, " ;");
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete newStr;
}
| DISPLAY_STATISTICS FORtoken PID PID_VALUE
{
// This is of the form "FOR PID \DOPEY.1,5"
identifier_name_internal2 = new char[strlen($4)+1];
str_cpy_convert (identifier_name_internal2, $4, strlen($4), TRUE);
identifier_name_internal2[strlen($4)] = 0;
}
stats_active_clause
{
pos_internal3 = $6;
}
stats_merge_clause
{
long strLen = 100 + strlen(identifier_name_internal2);
char *newStr = new char[strLen];
sprintf(newStr, "GET STATISTICS FOR PID %s ACTIVE %d",
identifier_name_internal2, pos_internal3);
if ($8 == SQLCLIDEV_ACCUMULATED_STATS)
strcat(newStr, " ACCUMULATED");
strcat(newStr, " ;");
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
delete identifier_name_internal2;
delete newStr;
}
| DISPLAY_STATISTICS FORtoken QID qid_identifier
{
get_stats_str = new char[strlen($4)+100];
sprintf(get_stats_str, "GET STATISTICS FOR QID %s", $4);
}
stats_merge_clause
{
char *newStr1 = new char[25];
if ($6 == SQLCLI_ACCUMULATED_STATS)
strcpy(newStr1, " ACCUMULATED");
else if ($6 == SQLCLI_PERTABLE_STATS)
strcpy(newStr1, " PERTABLE");
else if ($6 == SQLCLI_PROGRESS_STATS)
strcpy(newStr1, " PROGRESS");
else if ($6 == SQLCLI_SAME_STATS)
strcpy(newStr1, " DEFAULT");
else
strcpy(newStr1, "");
strcat(get_stats_str, newStr1);
strcat(get_stats_str, " ;");
$$ = new DML(get_stats_str, DML_DESCRIBE_TYPE, NULL);
// delete id name internal2 allocated in qid_identifier
if (identifier_name_internal2)
{
delete [] identifier_name_internal2;
identifier_name_internal2 = NULL;
}
delete [] get_stats_str;
delete [] newStr1;
}
| DISPLAY_QC
{
$$ = new QueryCacheSt(0);
}
| DISPLAY_QC_ENTRIES
{
$$ = new QueryCacheSt(1);
}
| DISPLAY_QC_ENTRIES_NOTIME
{
$$ = new QueryCacheSt(2);
}
| DISPLAY
{
pos_internal = 7;
}
dml_type
{
$$ = new DML(SqlciParse_OriginalStr, $3,
"__SQLCI_DML_DISPLAY__");
REPOSITION_SqlciParse_InputPos;
}
| GETtoken
{
$$ = new DML(SqlciParse_OriginalStr, DML_DISPLAY_NO_HEADING_TYPE, NULL);
REPOSITION_SqlciParse_InputPos;
}
| GETSTATISTICStoken
{
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
REPOSITION_SqlciParse_InputPos;
}
| GETtoken UIDtoken
{
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
REPOSITION_SqlciParse_InputPos;
}
| SETtoken ENVVARtoken IDENTIFIER
{
int i, len, quoted;
CharInfo::CharSet cs;
int inhexadecimal;
if (trimValueText(i, len, quoted, cs, inhexadecimal)) {sqlcierror("");YYERROR;}
char * evNam = new char[strlen($3)+1];
for (size_t k=0; k < strlen($3); k++)
{
evNam[k] = toupper($3[k]);
}
evNam[strlen($3)] = 0;
char * evVal = NULL;
if (len <= 0)
{
len = 1;
evVal = new char[len + 1];
strcpy(evVal, "1");
}
else
{
evVal = new char[len+1];
strncpy(evVal, &SqlciParse_OriginalStr[i], len);
evVal[len] = 0;
}
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
int j = setenv(evNam, evVal, 1);
if (j)
{
delete [] evNam;
delete [] evVal;
cerr << "*** ERROR " << j << " from putenv." << endl;
sqlcierror("");
YYERROR;
}
REPOSITION_SqlciParse_InputPos;
Envvar * envvar =
SqlciEnvGlobal->get_envvarlist()->get(evNam);
if (envvar)
{
envvar->setValue(evVal);
}
else
{
envvar = new Envvar(evNam, evVal);
SqlciEnvGlobal->get_envvarlist()->append(envvar);
}
delete [] evNam;
delete [] evVal;
}
| RESET ENVVARtoken IDENTIFIER
{
char * evNam = new char[strlen($3)+1];
for (size_t k=0; k < strlen($3); k++)
{
evNam[k] = toupper($3[k]);
}
evNam[strlen($3)] = 0;
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
long putenvLen = 0;
putenvLen += strlen(evNam);
putenvLen += strlen("=");
char * putenvStr = new char[putenvLen+1];
strcpy(putenvStr, evNam);
strcat(putenvStr, "=");
int j = 0;
NABoolean found = FALSE;
while ((ENVIRON[j]) && (NOT found))
{
if ((strlen(ENVIRON[j]) >= strlen(putenvStr)) &&
(memcmp(ENVIRON[j], putenvStr, strlen(putenvStr)) == 0))
{
found = TRUE;
}
else
j++;
}
if (found)
{
while (ENVIRON[j])
{
ENVIRON[j] = ENVIRON[j+1];
j++;
}
}
SqlciEnvGlobal->get_envvarlist()->remove(evNam);
delete [] evNam;
}
| SHOW ENVVARtoken
{
long newStrLen =
strlen("GET ENVVARS;");
char * newStr = new char[newStrLen+1];
strcpy(newStr, "GET ENVVARS;");
$$ = new DML(newStr, DML_SHOWSHAPE_TYPE, NULL);
delete newStr;
}
| SETtoken PARSERFLAGS NUMBER
{
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
}
| RESET PARSERFLAGS NUMBER
{
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
}
| RESET PARSERFLAGS
{
$$ = new DML(SqlciParse_OriginalStr, DML_DESCRIBE_TYPE, NULL);
}
| QUIESCE
{
$$ = new Quiesce();
}
| ERRORtoken NUMBER COMMA GETtoken
{
long newStrLen =
strlen("GET TEXT FOR ERROR ") + 20;
char * newStr = new char[newStrLen+1];
str_sprintf(newStr, "GET TEXT FOR ERROR %s", $2);
$$ = new DML(newStr, DML_DESCRIBE_TYPE, NULL);
}
| STOREtoken EXPLAIN FORtoken IDENTIFIER INtoken REPOSITORYtoken
{
identifier_name_internal = new char[strlen($4)+1];
str_cpy_convert(identifier_name_internal, $4, strlen($4), TRUE);
identifier_name_internal[strlen($4)] = 0;
$$ = new StoreExplain(identifier_name_internal);
}
optional_rs_index : empty
{
$$ = 0;
}
| RESULT SETtoken NUMBER
{
$$ = atoi($3);
}
cursor_info : dml_simple_table_type
{
char *queryText = &SqlciParse_OriginalStr[pos_internal];
char *queryTextCopy = new char[strlen(queryText) + 1];
strcpy(queryTextCopy, queryText);
SqlciCursorInfo *c = new SqlciCursorInfo();
c->queryTextSpecified_ = -1;
c->queryTextOrStmtName_ = queryTextCopy;
$$ = c;
}
| IDENTIFIER
{
// Not sure exactly why, but we must make a copy of
// the IDENTIFIER string now before more tokens are
// parsed. If we wait until the entire rule is
// matched, the IDENTIFIER string may not be valid
// anymore. The copy will be pointed to by a global
// variable and released later by the rule that
// contains cursor_info as a subrule.
identifier_name_internal2 = new char[strlen($1) + 1];
strcpy(identifier_name_internal2, $1);
}
optional_rs_index
{
SqlciCursorInfo *c = new SqlciCursorInfo();
c->queryTextSpecified_ = 0;
c->queryTextOrStmtName_ = identifier_name_internal2;
c->resultSetIndex_ = $3;
$$ = c;
}
dml_type :
dml_simple_table_type {}
| CONTROL {$$ = DML_CONTROL_TYPE;}
| OSIM {$$ = DML_OSIM_TYPE;}
| SETtoken CATALOG {$$ = DML_CONTROL_TYPE;}
| SETtoken SCHEMA {$$ = DML_CONTROL_TYPE;}
| SETtoken HIVEtoken {$$ = DML_CONTROL_TYPE;}
| SETtoken MPLOC {$$ = DML_CONTROL_TYPE;}
| SETtoken NAMETYPE {$$ = DML_CONTROL_TYPE;}
| SETtoken SESSIONtoken {$$ = DML_CONTROL_TYPE;}
| UPDATEtoken {$$ = DML_UPDATE_TYPE;}
| INSERTtoken {$$ = DML_INSERT_TYPE;}
| UPSERTtoken {$$ = DML_INSERT_TYPE;}
| ROWSETtoken {$$ = DML_INSERT_TYPE;}
| DELETEtoken {$$ = DML_DELETE_TYPE;}
| MERGEtoken {$$ = DML_UPDATE_TYPE;}
| CREATE {$$ = DML_DDL_TYPE;}
| ALTER {$$ = DML_DDL_TYPE;}
| CLEANUP {$$ = DML_DESCRIBE_TYPE;}
| DROP {$$ = DML_DDL_TYPE;}
| UPD_STATS {$$ = DML_DDL_TYPE;}
| UPD_HIST_STATS {$$ = DML_DDL_TYPE;}
| METADATAtoken {$$ = DML_DDL_TYPE;}
| INITIALIZE {$$ = DML_DESCRIBE_TYPE;}
| REINITIALIZE {$$ = DML_DDL_TYPE;}
| GIVE {$$ = DML_DDL_TYPE;}
| GRANTtoken {$$ = DML_DDL_TYPE;}
| REVOKEtoken {$$ = DML_DDL_TYPE;}
| REGISTER {$$ = DML_DDL_TYPE;}
| UNREGISTER {$$ = DML_DDL_TYPE;}
| SHOWCONTROL {$$ = DML_DESCRIBE_TYPE;}
| SHOWDDL {$$ = DML_DESCRIBE_TYPE;}
| SHOWSTATS {$$ = DML_DESCRIBE_TYPE;}
| SHOWTRANSACTION {$$ = DML_DESCRIBE_TYPE;}
| INVOKE {$$ = DML_DESCRIBE_TYPE;}
| SHOWPLAN {$$ = DML_DESCRIBE_TYPE;}
| SHOWSHAPE {$$ = DML_DESCRIBE_TYPE;}
| SHOWSET {$$ = DML_DESCRIBE_TYPE;}
| LOCK {$$ = DML_CONTROL_TYPE;}
| UNLOCK {$$ = DML_CONTROL_TYPE;}
| TOK_BEGIN {$$ = DML_CONTROL_TYPE;}
| COMMIT {$$ = DML_CONTROL_TYPE;}
| ROLLBACK {$$ = DML_CONTROL_TYPE;}
| SET_TABLEtoken {$$ = DML_CONTROL_TYPE;}
| SET_TRANSACTIONtoken {$$ = DML_CONTROL_TYPE;}
| MODIFY {$$ = DML_DDL_TYPE;}
| IF {$$ = DML_CONTROL_TYPE;}
| WHILE {$$ = DML_CONTROL_TYPE;}
| SIGNAL {$$ = DML_CONTROL_TYPE;}
| INTERNAL {$$ = DML_CONTROL_TYPE;}
| MVLOG {$$ = DML_CONTROL_TYPE;}
| PURGEDATA {$$ = DML_DDL_TYPE;}
| TRUNCATE {$$ = DML_DDL_TYPE;}
| WITH {$$ = DML_DDL_TYPE;}
| POPULATE {$$ = DML_DDL_TYPE;}
| VALIDATEtoken {$$ = DML_DDL_TYPE;}
| REFRESH {$$ = DML_DDL_TYPE;}
| TRANSFORM {$$ = DML_DDL_TYPE;}
| CALLToken {$$ = DML_DDL_TYPE;}
| LOADtoken {$$ = DML_DDL_TYPE;}
| MSCKtoken {$$ = DML_DDL_TYPE;}
| EXTRACTtoken {$$ = DML_DESCRIBE_TYPE;}
| REPLICATEtoken {$$ = DML_DESCRIBE_TYPE;}
| GENERATEtoken {$$ = DML_DESCRIBE_TYPE;}
| EXPLAIN {$$ = DML_DESCRIBE_TYPE;}
| GETtoken {$$ = DML_DESCRIBE_TYPE;}
| PROCESStoken {$$ = DML_DDL_TYPE;}
| COMMENTtoken {$$ = DML_DDL_TYPE;}
;
dml_simple_table_type :
SELECTtoken {$$ = DML_SELECT_TYPE;}
| TABLE {$$ = DML_SELECT_TYPE;}
| VALUES {$$ = DML_SELECT_TYPE;}
| LPAREN dml_simple_table_type {$$ = DML_SELECT_TYPE;}
| LOCKINGtoken {$$ = DML_SELECT_TYPE;}
| UNLOAD {$$ = DML_UNLOAD_TYPE;}
;
explain_options : empty
{
$$ = 0;
}
| OPTIONStoken QUOTED_STRING
{
if (strcmp($2, "f") != 0) // accept only old value
{
sqlci_DA << DgSqlCode(-15517);// say invalid option
YYERROR; // give up processing
}
else
{
$$ = $2;
}
}
;
shell_cmd :
CD
{
$$ = new Chdir(SqlciParse_OriginalStr);
REPOSITION_SqlciParse_InputPos;
}
| LS
{
$$ = new Ls(SqlciParse_OriginalStr);
REPOSITION_SqlciParse_InputPos;
}
| SHELL
{
$$ = new Shell(SqlciParse_OriginalStr);
REPOSITION_SqlciParse_InputPos;
}
;
%%