У меня есть Native Impala UDF (Cpp) с двумя функциями Обе функции дополняют друг друга.Native Impala UDF (Cpp) случайным образом дает результат как NULL для одних и тех же входов в одной таблице для нескольких вызовов в одном запросе
String myUDF(BigInt)
BigInt myUDFReverso(String)
myUDF("myInput")
дает некоторый вывод, который когда myUDFReverso(myUDF("myInput"))
должен отдать myInput
Когда я бегу импала запрос на столе паркет, как это,
select column1,myUDF(column1),length(myUDF(column1)),myUDFreverso(myUDF(column1)) from my_parquet_table order by column1 LIMIT 10;
Выход случайным NULL ,
Выход говорят на 1-м ходу, как,
+------------+----------------------+------------------------+-------------------------------------+
| column1 | myDB.myUDF(column1) | length(myUDF(column1)) | myDB.myUDFReverso(myUDF(column1)) |
+------------+----------------------+------------------------+-------------------------------------+
| 27011991 | 1.0.128.9 | 9 | 27011991 |
| 27011991 | 1.0.128.9 | 9 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | 14022013 |
| 14022013 | 1.0.131.239 | 11 | NULL |
+------------+----------------------+------------------------+-------------------------------------+
и предположим, на 2-м ходу,
+------------+----------------------+------------------------+-------------------------------------+
| column1 | myDB.myUDF(column1) | length(myUDF(column1)) | myDB.myUDFReverso(myUDF(column1)) |
+------------+----------------------+------------------------+-------------------------------------+
| 27011991 | 1.0.128.9 | 9 | 27011991 |
| 27011991 | 1.0.128.9 | 9 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | 14022013 |
| 14022013 | 1.0.131.239 | 11 | 14022013 |
| 14022013 | 1.0.131.239 | 11 | NULL |
| 14022013 | 1.0.131.239 | 11 | 14022013 |
| 14022013 | 1.0.131.239 | 11 | NULL |
+------------+----------------------+------------------------+-------------------------------------+
И иногда это дает правильное значение для всех строк тоже.
Я испытал это на Impala v1.2.4, а также v2.1 Что является причиной этого? Проблема с памятью?
Edit 1:
BigIntVal myUDF(FunctionContext* context, const StringVal& myInput)
{
if (myInput.is_null) return BigIntVal::null();
unsigned int temp_op= 0;
unsigned long result= 0;
uint8_t *p;
char c= '.';
p=myInput.ptr;
while (*p != '\0')
{
c= *p++;
int digit= c*2;
if (digit >= 22 && digit <= 31)
{
if ((temp_op= temp_op * 10 - digit) > 493)
{
return BigIntVal::null();
}
}
else if (c == '.')
{
result= (result << 8) + (unsigned long) temp_op;
temp_op= 0;
}
else
{
return BigIntVal::null();
}
}
return BigIntVal((result << 8) + (unsigned long) temp_op);
}
In .h file the macro lowerbytify is defined as
#define lowerbytify(T,A) { *(T)= (char)((A));\
*((T)+1)= (char)(((A) >> 8));\
*((T)+2)= (char)(((A) >> 16));\
*((T)+3)= (char)(((A) >> 24)); }
StringVal myUDFReverso(FunctionContext* context, const BigIntVal& origMyInput)
{
if (origMyInput.is_null)
return StringVal::null();
int64_t myInput=origMyInput.val;
char myInputArr[16];
unsigned int l=0;
unsigned char temp[8];
lowerbytify(temp, myInput);
char calc[4];
calc[3]= '.';
for (unsigned char *p= temp + 4; p-- > temp;)
{
unsigned int c= *p;
unsigned int n1, n2;
n1= c/100;
c-= n1 * 100;
n2= c/10;
c-= n2 * 10;
calc[0]= (char) n1 + '0';
calc[1]= (char) n2 + '0';
calc[2]= (char) c + '0';
unsigned int length= (n1 ? 4 : (n2 ? 3 : 2));
unsigned int point= (p <= temp) ? 1 : 0;
char * begin = &calc[4-length];
for(int step = length - point;step>0;step--,l++,begin++)
{
myInputArr[l]=*begin;
}
}
myInputArr[l]='\0';
StringVal result(context,l);
memcpy(result.ptr, myInputArr,l);
return result;
}
Я подозреваю, что это проблема с управлением памятью. Можете ли вы поделиться своим кодом UDF? – Matt
@matt Обновлено мой вопрос –