blob: c32686e1710a4ae4fd92c41863b596fa77d6e182 [file] [log] [blame]
/* -*-C++-*-
**********************************************************************
*
* File: LmRoutineCSql.cpp
* Description:
* Created: 08/02/2009
* Language: C++
*
// @@@ 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 @@@
**********************************************************************/
#include "LmRoutineCSql.h"
#include "LmParameter.h"
#include "sqludr.h"
#include "ComDefs.h"
#include "wstr.h"
// Routine body signatures
typedef Lng32 (*UDRFN1) (char*,
short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN2) (char*,char*,
short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN3) (char*,char*,char*,
short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN4) (char*,char*,char*,char*,
short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN5) (char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN6) (char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN7) (char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN8) (char*,char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN9) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN10) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN11) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN12) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN13) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN14) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN15) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN16) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN17) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN18) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN19) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN20) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN21) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN22) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN23) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN24) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN25) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN26) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN27) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN28) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN29) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN30) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN31) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,
SQLUDR_TRAIL_ARGS);
typedef Lng32 (*UDRFN32) (char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
char*,char*,char*,char*,char*,char*,char*,char*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,short*,short*,short*,
short*,short*,short*,short*,
SQLUDR_TRAIL_ARGS);
// SQLUDR_INVOKE is a global function that acts as the gateway into
// the routine body. It only contains a switch construct and calls
// appropriate function pointer depending on the argc parameter.
ComSInt32 SQLUDR_INVOKE(void *fp,
SQLUDR_UINT32 argc,
char **data,
short *ind,
SQLUDR_CHAR sqlState[SQLUDR_SQLSTATE_SIZE],
SQLUDR_CHAR msgText[SQLUDR_MSGTEXT_SIZE],
SQLUDR_INT32 callType,
SQLUDR_STATEAREA *stateArea,
SQLUDR_UDRINFO *udrInfo)
{
ComSInt32 rc = 0;
switch (argc)
{
case 1:
rc = ((UDRFN1) fp) (data[0],
&ind[0],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 2:
rc = ((UDRFN2) fp) (data[0], data[1],
&ind[0], &ind[1],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 3:
rc = ((UDRFN3) fp) (data[0], data[1], data[2],
&ind[0], &ind[1], &ind[2],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 4:
rc = ((UDRFN4) fp) (data[0], data[1], data[2], data[3],
&ind[0], &ind[1], &ind[2], &ind[3],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 5:
rc = ((UDRFN5) fp) (data[0], data[1], data[2], data[3],
data[4],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 6:
rc = ((UDRFN6) fp) (data[0], data[1], data[2], data[3],
data[4], data[5],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 7:
rc = ((UDRFN7) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 8:
rc = ((UDRFN8) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 9:
rc = ((UDRFN9) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 10:
rc = ((UDRFN10) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 11:
rc = ((UDRFN11) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 12:
rc = ((UDRFN12) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 13:
rc = ((UDRFN13) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 14:
rc = ((UDRFN14) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 15:
rc = ((UDRFN15) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 16:
rc = ((UDRFN16) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 17:
rc = ((UDRFN17) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 18:
rc = ((UDRFN18) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 19:
rc = ((UDRFN19) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 20:
rc = ((UDRFN20) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 21:
rc = ((UDRFN21) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 22:
rc = ((UDRFN22) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 23:
rc = ((UDRFN23) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 24:
rc = ((UDRFN24) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 25:
rc = ((UDRFN25) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 26:
rc = ((UDRFN26) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 27:
rc = ((UDRFN27) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25], data[26],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25], &ind[26],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 28:
rc = ((UDRFN28) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25], data[26], data[27],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25], &ind[26], &ind[27],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 29:
rc = ((UDRFN29) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25], data[26], data[27],
data[28],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25], &ind[26], &ind[27],
&ind[28],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 30:
rc = ((UDRFN30) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25], data[26], data[27],
data[28], data[29],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25], &ind[26], &ind[27],
&ind[28], &ind[29],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 31:
rc = ((UDRFN31) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25], data[26], data[27],
data[28], data[29], data[30],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25], &ind[26], &ind[27],
&ind[28], &ind[29], &ind[30],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
case 32:
rc = ((UDRFN32) fp) (data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19],
data[20], data[21], data[22], data[23],
data[24], data[25], data[26], data[27],
data[28], data[29], data[30], data[31],
&ind[0], &ind[1], &ind[2], &ind[3],
&ind[4], &ind[5], &ind[6], &ind[7],
&ind[8], &ind[9], &ind[10], &ind[11],
&ind[12], &ind[13], &ind[14], &ind[15],
&ind[16], &ind[17], &ind[18], &ind[19],
&ind[20], &ind[21], &ind[22], &ind[23],
&ind[24], &ind[25], &ind[26], &ind[27],
&ind[28], &ind[29], &ind[30], &ind[31],
sqlState, msgText, callType,
stateArea, udrInfo);
break;
default:
LM_ASSERT1(0, "Parameters more than 32 are not allowed.");
break;
}
return rc;
} // SQLUDR_INVOKE
LmRoutineCSql::LmRoutineCSql(const char *sqlName,
const char *externalName,
const char *librarySqlName,
ComUInt32 numSqlParam,
char *routineSig,
ComUInt32 maxResultSets,
ComRoutineTransactionAttributes transactionAttrs,
ComRoutineSQLAccess sqlAccessMode,
ComRoutineExternalSecurity externalSecurity,
Int32 routineOwnerId,
const char *parentQid,
ComUInt32 inputRowLen,
ComUInt32 outputRowLen,
const char *currentUserName,
const char *sessionUserName,
LmParameter *parameters,
LmLanguageManagerC *lm,
LmHandle routine,
LmContainer *container,
ComDiagsArea *diagsArea)
: LmRoutineC(sqlName, externalName, librarySqlName, numSqlParam, routineSig,
maxResultSets,
COM_LANGUAGE_C,
COM_STYLE_SQL,
transactionAttrs,
sqlAccessMode,
externalSecurity,
routineOwnerId,
parentQid, inputRowLen, outputRowLen,
currentUserName, sessionUserName,
parameters, lm, routine, container, diagsArea),
cBuf_(NULL),
data_(NULL),
ind_(numSqlParam * sizeof(short))
{
ComUInt32 i = 0;
data_ = (char **) collHeap()->allocateMemory(numSqlParam * sizeof(char *));
// Allocate C data buffers. Each LmCBuffer instance points to a C
// buffer and the data_ buffer is an array of pointers to the C data
// buffers. The LmCBuffer is mainly used to track the actual size of
// the C buffers because each buffer has some extra bytes at the end
// to protect against buffer overwrites.
//
// cBuf_ -> LmCBuffer LmCBuffer LmCBuffer ...
// | | |
// v v v
// buffer buffer buffer ...
// ^ ^ ^
// | | |
// data_[0] data_[1] data_[2] ...
//
// NOTE: the cBuf_ array is allocated on the C++ heap because we
// want to manage the collection as a single array, and we want
// constructors and destructors to be called when the collection is
// created and destroyed. Right now, NAMemory and NABasic object
// interfaces do not provide the appropriate array versions of new
// and delete operators to accomplish these things.
cBuf_ = new LmCBuffer[numSqlParam_];
LM_ASSERT(cBuf_);
for (i = 0; i < numSqlParam_; i++)
{
LmParameter &p = lmParams_[i];
LmCBuffer &cBuf = cBuf_[i];
ComUInt32 dataBytes = 0;
switch (p.direction())
{
// NOTE: The code currently supports IN and OUT parameters for C
// routines. There is no reason we couldn't support INOUT as
// well, which will be needed if we ever provide stored
// procedures written in C. But the INOUT code paths have not
// been implemented yet.
case COM_INPUT_COLUMN:
dataBytes = p.inSize();
break;
case COM_OUTPUT_COLUMN:
dataBytes = p.outSize();
break;
default:
LM_ASSERT(0);
break;
}
switch (p.fsType())
{
case COM_VCHAR_FSDT:
case COM_VCHAR_DBL_FSDT:
{
// VARCHAR(N) CHARACTER SET ISO88591
// VARCHAR(N) CHARACTER SET UCS2
// This is a VARCHAR parameter. Allocate one buffer that will
// hold the VC struct and the data. Data will begin at the first
// 8-byte boundary following the VC struct.
ComUInt32 vcBytes = ROUND8(sizeof(SQLUDR_VC_STRUCT)) + dataBytes;
cBuf.init(vcBytes);
data_[i] = cBuf.getBuffer();
// Initialize the VC struct
SQLUDR_VC_STRUCT *vc = (SQLUDR_VC_STRUCT *) cBuf.getBuffer();
char *charPtr = (char *) vc;
vc->data = charPtr + ROUND8(sizeof(SQLUDR_VC_STRUCT));
vc->length = dataBytes;
}
break;
case COM_FCHAR_FSDT:
case COM_FCHAR_DBL_FSDT:
case COM_SIGNED_DECIMAL_FSDT:
case COM_UNSIGNED_DECIMAL_FSDT:
case COM_DATETIME_FSDT:
case COM_SIGNED_NUM_BIG_FSDT:
case COM_UNSIGNED_NUM_BIG_FSDT:
{
// CHAR(N) CHARACTER SET ISO88591
// CHAR(N) CHARACTER SET UCS2
// DECIMAL [UNSIGNED]
// DATE, TIME, TIMESTAMP
// NUMERIC precision > 18
// These types require a null-terminated C string. Add one to
// dataBytes to account for the null terminator.
cBuf.init(dataBytes + 1);
data_[i] = cBuf.getBuffer();
}
break;
default:
{
// All other types
cBuf.init(dataBytes);
data_[i] = cBuf.getBuffer();
}
break;
} // switch (p.fsType())
} // for each param
} // LmRoutineCSql::LmRoutineCSql
LmRoutineCSql::~LmRoutineCSql()
{
// Free each C buffer then free the memory for the LmCBuffer
// instances
for (ComUInt32 i = 0; i < numSqlParam_; i++)
{
LmCBuffer &cBuf = cBuf_[i];
cBuf.release();
}
delete [] cBuf_;
}
LmResult LmRoutineCSql::invokeRoutine(void *inputRow,
void *outputRow,
ComDiagsArea *da)
{
ComUInt32 argc = numSqlParam_;
ComUInt32 i = 0;
short *udrInd = (short *) ind_.getBuffer();
// Code handles UDF functions with upto 32 parameters.
LM_ASSERT1(argc <= 32, "Parameters more than 32 are not allowed.");
// We can return early if the caller is requesting a FINAL call but
// not FINAL is necessary because the INITIAL call was never made
if (callType_ == SQLUDR_CALLTYPE_FINAL && !finalCallRequired_)
return LM_OK;
ComUInt32 numIn = 0;
ComUInt32 numOut = 0;
// Build the argument vector
if (callType_ != SQLUDR_CALLTYPE_FINAL)
{
for (i = 0; i < argc; i++)
{
LmParameter &p = lmParams_[i];
LM_ASSERT1(p.direction() != COM_INOUT_COLUMN,
"INOUT parameters are not supported for C routines");
if (p.isIn())
{
numIn++;
// Set the input null indicator
NABoolean nullVal = p.isNullInput((char *) inputRow);
udrInd[i] = (nullVal ? SQLUDR_NULL : SQLUDR_NOTNULL);
// Make a copy of the input value
if (! nullVal)
{
char *inData = ((char *) inputRow) + p.inDataOffset();
char *inCopy = data_[i];
ComUInt32 inBytes = p.inSize();
switch (p.fsType())
{
case COM_FCHAR_FSDT:
{
// CHAR(N) CHARACTER SET ISO88591
memcpy(inCopy, inData, inBytes);
inCopy[inBytes] = 0;
}
break;
case COM_FCHAR_DBL_FSDT:
{
// CHAR(N) CHARACTER SET UCS2
memcpy(inCopy, inData, inBytes);
inCopy[inBytes] = 0;
inCopy[inBytes + 1] = 0;
}
break;
case COM_VCHAR_FSDT:
case COM_VCHAR_DBL_FSDT:
{
// VARCHAR(N) CHARACTER SET ISO88591
// VARCHAR(N) CHARACTER SET UCS2
SQLUDR_VC_STRUCT *vc = (SQLUDR_VC_STRUCT *) inCopy;
ComUInt32 inDataLen = p.actualInDataSize(inputRow);
memcpy(&(vc->length), &inDataLen, 4);
memcpy(vc->data, inData, inDataLen);
}
break;
case COM_SIGNED_BIN8_FSDT:
case COM_UNSIGNED_BIN8_FSDT:
{
// TINYINT [UNSIGNED]
// NUMERIC 0 <= precision <= 3
memcpy(inCopy, inData, 1);
}
break;
case COM_SIGNED_BIN16_FSDT:
case COM_UNSIGNED_BIN16_FSDT:
{
// SMALLINT [UNSIGNED]
// NUMERIC 0 <= precision <= 4
memcpy(inCopy, inData, 2);
}
break;
case COM_SIGNED_BIN32_FSDT:
case COM_UNSIGNED_BIN32_FSDT:
case COM_FLOAT32_FSDT:
{
// INTEGER [UNSIGNED]
// REAL
// NUMERIC 5 <= precision <= 9
memcpy(inCopy, inData, 4);
}
break;
case COM_SIGNED_BIN64_FSDT:
case COM_FLOAT64_FSDT:
{
// LARGEINT
// FLOAT
// DOUBLE PRECISION
// NUMERIC 10 <= precision <= 18
memcpy(inCopy, inData, 8);
}
break;
case COM_SIGNED_DECIMAL_FSDT:
case COM_UNSIGNED_DECIMAL_FSDT:
case COM_DATETIME_FSDT:
case COM_SIGNED_NUM_BIG_FSDT:
case COM_UNSIGNED_NUM_BIG_FSDT:
{
// DECIMAL [UNSIGNED]
// DATE, TIME, TIMESTAMP
// NUMERIC precision > 18
memcpy(inCopy, inData, inBytes);
inCopy[inBytes] = '\0';
}
break;
default:
{
char msg[256];
sprintf(msg, "Unknown parameter type: %d", p.fsType());
LM_ASSERT1(0, msg);
}
break;
} // switch (p.fsType())
} // if not null
} // if (isInput)
else
{
numOut++;
// Set the output null indicator
udrInd[i] = SQLUDR_NOTNULL;
// Initialize the output buffer
char *outData = (char *)outputRow + p.outDataOffset();
char *outCopy = data_[i];
ComUInt32 outBytes = p.outSize();
switch (p.fsType())
{
case COM_FCHAR_FSDT:
{
// CHAR(N) CHARACTER SET ISO88591
memset(outCopy, ' ', outBytes);
outCopy[outBytes] = 0;
}
break;
case COM_FCHAR_DBL_FSDT:
{
// CHAR(N) CHARACTER SET UCS2
NAWchar *wOutCopy = (NAWchar *) outCopy;
ComUInt32 outChars = outBytes / sizeof(NAWchar);
wc_str_pad(wOutCopy, outChars); // pads with space by default
wOutCopy[outChars] = 0;
}
break;
case COM_VCHAR_FSDT:
case COM_VCHAR_DBL_FSDT:
{
// VARCHAR(N) CHARACTER SET ISO88591
// VARCHAR(N) CHARACTER SET UCS2
SQLUDR_VC_STRUCT *vc = (SQLUDR_VC_STRUCT *) outCopy;
vc->length = outBytes;
memset(vc->data, 0, outBytes);
}
break;
case COM_SIGNED_BIN8_FSDT:
case COM_UNSIGNED_BIN8_FSDT:
{
// TINYINT [UNSIGNED]
// NUMERIC 0 <= precision <= 3
memset(outCopy, 0, 1);
}
break;
case COM_SIGNED_BIN16_FSDT:
case COM_UNSIGNED_BIN16_FSDT:
{
// SMALLINT [UNSIGNED]
// NUMERIC 0 <= precision <= 4
memset(outCopy, 0, 2);
}
break;
case COM_SIGNED_BIN32_FSDT:
case COM_UNSIGNED_BIN32_FSDT:
case COM_FLOAT32_FSDT:
{
// INTEGER [UNSIGNED]
// REAL
// NUMERIC 5 <= precision <= 9
memset(outCopy, 0, 4);
}
break;
case COM_SIGNED_BIN64_FSDT:
case COM_FLOAT64_FSDT:
{
// LARGEINT
// FLOAT
// DOUBLE PRECISION
// NUMERIC 10 <= precision <= 18
memset(outCopy, 0, 8);
}
break;
case COM_SIGNED_DECIMAL_FSDT:
case COM_UNSIGNED_DECIMAL_FSDT:
case COM_DATETIME_FSDT:
case COM_SIGNED_NUM_BIG_FSDT:
case COM_UNSIGNED_NUM_BIG_FSDT:
{
// DECIMAL [UNSIGNED]
// DATE, TIME, TIMESTAMP
// NUMERIC precision > 18
memset(outCopy, ' ', outBytes);
outCopy[outBytes] = 0;
}
break;
default:
{
char msg[256];
sprintf(msg, "Unknown parameter type value: %d", p.fsType());
LM_ASSERT1(0, msg);
}
break;
} // switch (p.fsType())
} // if (isInput) else ...
} // for each parameter
} // if this is not a FINAL call
else
{
// This is a FINAL call. Set all null indicators to SQLUDR_NULL
// and zero out data buffers.
for (i = 0; i < argc; i++)
{
udrInd[i] = SQLUDR_NULL;
LmCBuffer &cBuf = cBuf_[i];
cBuf.set(0);
}
}
// Initialize SQLSTATE to all '0' characters and add a null terminator
str_pad(sqlState_, SQLUDR_SQLSTATE_SIZE - 1, '0');
sqlState_[SQLUDR_SQLSTATE_SIZE - 1] = 0;
// Initialize SQL text to all zero bytes
str_pad(msgText_, SQLUDR_MSGTEXT_SIZE, '\0');
// Now we can call the routine body...
ComSInt32 rc = SQLUDR_INVOKE(routine_, argc, data_, udrInd,
sqlState_, msgText_, callType_,
stateArea_, udrInfo_);
// Set the call type for the next invocation to NORMAL if this is
// an INITIAL call
if (callType_ == SQLUDR_CALLTYPE_INITIAL)
{
callType_ = SQLUDR_CALLTYPE_NORMAL;
finalCallRequired_ = TRUE;
}
else if (callType_ == SQLUDR_CALLTYPE_FINAL)
{
// We are done if this is a FINAL call
finalCallRequired_ = FALSE;
return LM_OK;
}
LmResult lmResult = LM_OK;
if (rc != SQLUDR_ERROR)
{
// Copy data and null indicator to caller's output buffers
for (i = numIn; i < argc && lmResult == LM_OK; i++)
{
LmParameter &p = lmParams_[i];
NABoolean isOutput = (p.direction() == COM_OUTPUT_COLUMN ? TRUE : FALSE);
if (isOutput)
{
// Look at the returned null indicator. Raise an error if the
// routine returned an invalid null indicator.
NABoolean isNull = TRUE;
switch(udrInd[i])
{
case SQLUDR_NOTNULL:
isNull = FALSE;
break;
case SQLUDR_NULL:
break;
default:
{
*da << DgSqlCode(-LME_UDF_INVALID_DATA)
<< DgString0(getNameForDiags())
<< DgInt0((Lng32) i + 1)
<< DgString1("Invalid null indicator");
lmResult = LM_ERR;
}
break;
}
// Write the null indicator into the output row
if (lmResult == LM_OK)
p.setNullOutput((char *) outputRow, isNull);
// If value is not NULL, set data.
if (lmResult == LM_OK && !isNull)
{
char *outData = ((char *)outputRow) + p.outDataOffset();
char *outCopy = data_[i];
ComUInt32 outBytes = p.outSize();
switch (p.fsType())
{
case COM_FCHAR_FSDT:
case COM_FCHAR_DBL_FSDT:
{
// CHAR(N) CHARACTER SET ISO88591
// CHAR(N) CHARACTER SET UCS2
p.setOutChar(outputRow, outCopy, outBytes);
}
break;
case COM_VCHAR_FSDT:
case COM_VCHAR_DBL_FSDT:
{
// VARCHAR(N) CHARACTER SET ISO88591
// VARCHAR(N) CHARACTER SET UCS2
SQLUDR_VC_STRUCT *vc = (SQLUDR_VC_STRUCT *) outCopy;
if (vc->length > outBytes)
{
char msg[100];
sprintf(msg, "VARCHAR length should not exceed %d",
outBytes);
*da << DgSqlCode(-LME_UDF_INVALID_DATA)
<< DgString0(getNameForDiags())
<< DgInt0((Lng32) i + 1)
<< DgString1(msg);
lmResult = LM_ERR;
}
else
{
p.setOutChar(outputRow, vc->data, vc->length);
}
}
break;
case COM_SIGNED_BIN8_FSDT:
case COM_UNSIGNED_BIN8_FSDT:
{
// TINYINT [UNSIGNED]
// NUMERIC 0 <= precision <= 3
memcpy(outData, outCopy, 1);
}
break;
case COM_SIGNED_BIN16_FSDT:
case COM_UNSIGNED_BIN16_FSDT:
{
// SMALLINT [UNSIGNED]
// NUMERIC 0 <= precision <= 4
memcpy(outData, outCopy, 2);
}
break;
case COM_SIGNED_BIN32_FSDT:
case COM_UNSIGNED_BIN32_FSDT:
case COM_FLOAT32_FSDT:
{
// INTEGER [UNSIGNED]
// REAL
// NUMERIC 5 <= precision <= 9
memcpy(outData, outCopy, 4);
}
break;
case COM_SIGNED_BIN64_FSDT:
case COM_FLOAT64_FSDT:
{
// LARGEINT
// FLOAT
// DOUBLE PRECISION
// NUMERIC 10 <= precision <= 18
memcpy(outData, outCopy, 8);
}
break;
case COM_SIGNED_DECIMAL_FSDT:
case COM_UNSIGNED_DECIMAL_FSDT:
case COM_DATETIME_FSDT:
case COM_SIGNED_NUM_BIG_FSDT:
case COM_UNSIGNED_NUM_BIG_FSDT:
{
// DECIMAL [UNSIGNED]
// DATE, TIME, TIMESTAMP
// NUMERIC precision > 18
p.setOutChar(outputRow, outCopy, outBytes);
}
break;
default:
{
char msg[256];
sprintf(msg, "Unknown parameter type value: %d", p.fsType());
LM_ASSERT1(0, msg);
}
break;
} // switch (p.fsType())
} // if (lmResult == LM_OK && !isNull)
} // if (isOutput)
} // for each LmParameter
} // if (rc != SQLUDR_ERROR)
if (lmResult == LM_OK && rc != SQLUDR_SUCCESS)
{
sqlState_[SQLUDR_SQLSTATE_SIZE - 1] = 0;
lmResult = processReturnStatus(rc, da);
}
return lmResult;
} // LmRoutineCSql::invokeRoutine